可能两者都没有。
我怀疑你应该拥有的是:
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
,但如果你T
是一个int&
,你只接受非常量左值int
,如果T
是一个int const&
,你接受任何可转换为的值int
.
这将是对NodeBase
. 我可以想到可能会出现这种情况的情况,但它们并不常见。
假设您只是想NodeBase
存储该数据,T&&
那么接受构造函数不是正确的做法——如果您存储的是int
in NodeBase
,您可能愿意复制 that int
,而不是只接受 move-from int
。
上面的代码正是这样做的——它允许任何可以存储在 中的东西都可以NodeBase
通过NodeBase
完美的转发传递给 。
另一方面,如果你真的想要一组奇怪的构造限制,那么这对你来说不是正确的答案。我在template
构建从通用引用参数构建的类型时使用过它,并且我确实想限制传入的类型以完全匹配通用引用参数,并在参数是右值引用时存储它,否则保留对它的引用。