7

現在、私のおもちゃクラス テンプレートの 1 つには、非常によく似た 2 つのコンストラクターがあります。

optional(const T& x)
{
    construct(x);
}

optional(T&& x)
{
    construct(std::move(x));
}

それらを単一のコンストラクター テンプレートに結合できますか、それともセマンティクスが何らかの形で変更されますか?

template<typename U>
optional(U&& x)
{
    construct(std::forward<U>(x));
}
4

4 に答える 4

4

申し訳ありませんが、テンプレート化されたコンストラクターは (コンパイラーによってコピー コンストラクターと見なされる) ことはありません。

于 2011-09-12T13:18:21.773 に答える
2

などの特性std::is_constructiblestd::is_convertible相互作用の方法を変更しoptionalます。たとえば、次のようになります。

class A {};

int main()
{
    std::cout << std::is_constructible<optional<A>, int>::value << '\n';
};

元のコードは次のように出力されます。

0

ただし、新しいコードは次のように出力されます。

1

これが望ましくなく、それでも新しいコードを使用したい場合は、受け入れ可能なタイプenable_ifに制限Uすることができます。

私が見る他の唯一の考えられる問題はT、参照型である可能性があるかどうかです(例int&)。その場合、元のコードの2番目のコンストラクターは、右辺値を渡すため疑わしいように見え、その右辺値を非定数左辺値参照にバインドしようとしている可能性があります(確実にはわかりません)。参照型になることができない場合Tは、これについて心配する必要はありません。

于 2011-09-12T14:39:25.977 に答える
1

ああ、constructはコンストラクターではなく、メンバー関数テンプレートです。

次に、セマンティクスが異なる可能性があります。元のオーバーロードセットは、左辺値参照をconstに渡すか、右辺値参照をnon-constに渡します。テンプレートバージョンは、左辺値参照をconstに渡すこともできます。(私はconstへの右辺値の参照を無視しています。)

ただし、すべての可能性で、construct受け入れるように宣言されておりU&&(そうでない場合、移動する以前のオーバーロードTは機能しません)、この場合非定数左辺値を処理する必要があります。または、受け入れるように宣言されてU const&おり、この場合は無害です。

于 2011-09-12T13:57:12.353 に答える
0

少なくともconstruct(const T& x)、場合によっては追加がconstruct(T&& x)定義されていて、型Uのオブジェクトが型のオブジェクトに変換可能であると仮定するとT、問題ないはずです...

  1. タイプの定数l値参照はUにバインドされますconstruct(const T& x)
  2. タイプの非定数l値参照はUにバインドされますconstruct(const T& x)
  3. タイプの一時的なr値は、r値参照バージョンが定義されていない場合にUバインドされますconstruct(T&& x)construct(const T& x)
  4. タイプの定数r値参照はUにバインドされますconstruct(const T& x)
于 2011-09-12T14:03:22.460 に答える