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

これらの4つのコンストラクターの1つがバインドされてディスパッチされる場所のすべての可能な使用法のセットUを検討してください。X

たとえば、Uの1つの要素は次のとおりです。

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

ここで、次のように5番目のコンストラクターを追加するとします。

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

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

Uの要素の1つが、、、または以前のように、より適切に一致するようにディスパッチされる新しいオーバーロード解決策はあり(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) のみを処理する 1 つのテンプレート コンストラクターを持つことである場合、次のような方法で他のものを「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 に答える