2
struct X
{
    X(X&);         // (1)
    X(X&&);        // (2)
    X(const X&);   // (3)
    X(const X&&);  // (4)
};

考虑将绑定和分派这四个构造函数之一的所有可能用法的集合U。X

例如,U的一个元素是:

int main()
{
    X x1 = ...;
    X x2(x1);  // <-- (1) used
}

现在想象我们添加第五个构造函数,如下所示:

struct X
{
    X(X&);                    // (1)
    X(X&&);                   // (2)
    X(const X&);              // (3)
    X(const X&&);             // (4)

    template<class T> X(T&&); // (5)
};

是否有任何新的重载解决方案,其中U的元素之一现在将(5)作为更好的匹配而不是(1),(2)或以前那样(3)调度?(4)

4

3 回答 3

4

考虑派生类:

struct Y : X
{ Y() { } };

int main()
{
  Y y;
  X x1(y); // derived class
}
于 2012-12-31T10:50:09.283 回答
2

好的,我现在明白了。我想,这种情况适用于任何可转换为 X 的 T。例如:

struct R
{
 operator X() const;
};

int main()
{
  R r{};
  X x{r};
}

如果您的目标是拥有一个仅处理您的 (1) 到 (4) 的模板构造函数,而没有其他内容,则您必须通过以下方式“SFINAE 离开”其他人:

template <typename T, typename U>
constexpr bool IsSame() {
  return is_same<
    typename decay<T>::type, 
    typename decay<U>::type
  >::value;
}

struct X
{
  template <class T, typename enable_if<IsSame<T, X>()>::type* = 0> 
  X(T&&);
};

或者,如果您的目标是将 T 可转换为 X 与其他 T 区分开来,请考虑以下解决方案:

struct X
{
  template <
    class T, 
    typename enable_if<is_convertible<T, X>::value>::type* = 0
  > 
  X(T&&); // do something

  template <
    class T, 
    typename enable_if<!is_convertible<T, X>::value>::type* = 0
  > 
  X(T&&); // do something else
};
于 2012-12-31T11:10:00.517 回答
-1
int main()
{
    X x2(12);  // <-- (5) used
}

(推导 T 为 int)

于 2012-12-31T10:55:53.750 回答