おそらくどちらでもない。
あなたが持っているべきだと思うものは次のとおりです。
template<class T>
struct NodeBase
{
T value;
NodeBase(NodeBase &&) = default;
NodeBase(NodeBase const&) = default; // issue: this might not work with a `T&`, but we can conditionally exclude it through some more fancy footwork
NodeBase(NodeBase &) = default;
template<typename U, typename=typename std:enable_if< std::is_convertible<U&&, T>::value >::type >
NodeBase(U &&u)
: value(std::forward<U>(u)) { }
};
template<class T>
struct Node : public NodeBase<T>
{
Node( Node & ) = default;
Node( Node const& ) = default; // issue: this might not work with a `T&`, but we can conditionally exclude it through some more fancy footwork
Node( Node && ) = default;
template<typename U, typename=typename std:enable_if< std::is_convertible<U&&, NodeBase<T>>::value >::type>
Node(U && u)
: NodeBase( std::forward<U>(u) ) { }
};
よほど変なことをしていない限り。
非常に奇妙なことですが、T
が の場合int
、移動元の値のみを に受け入れたいのですNode
が、 が の場合、非 const 左辺値のみを受け入れ、T
がの場合、変換可能な任意の値を受け入れることを意味します。.int&
int
T
int const&
int
これは、 のコンストラクターに配置する奇妙な一連の要件になりますNodeBase
。これが当てはまる状況を考えることはできますが、一般的ではありません。
NodeBase
そのデータを単に保存したいだけだと仮定するとT&&
、コンストラクターを取り込むことは正しいことではありません。int
inを保存している場合は、moved-from のみを受け入れるのではなく、NodeBase
そのコピーを作成することをいとわないでしょう。int
int
上記のコードはまさにそれを行います。これにより、 に保存できるものはすべて、完全に転送NodeBase
されて、 said に渡されます。NodeBase
一方、実際に奇妙な一連の構築制限が必要な場合、これは正しい答えではありません。ユニバーサル参照引数から構築された型を構築するときにそれを使用しましたがtemplate
、渡された型をユニバーサル参照引数と正確に一致するように制限し、引数が右辺値参照である場合はそれを保存したかったのですが、それ以外の場合は、それへの参照を保持します。