我在这里使用std :: forward或std :: move吗?

Meh*_*dad 10 c++ rvalue-reference move-semantics c++11

比方说我有:

template<class T>
struct NodeBase
{
    T value;
    NodeBase(T &&value)
        : value(value) { }
};
Run Code Online (Sandbox Code Playgroud)

我继承了它:

template<class T>
struct Node : public NodeBase<T>
{
    Node(T &&value)
        : NodeBase( WHAT_GOES_HERE (value)) { }
};
Run Code Online (Sandbox Code Playgroud)

应该WHAT_GOES_HEREstd::movestd::forward<T>?为什么?

jog*_*pan 6

因为在构造函数的实现中,Node<T>不知道T是普通类型(即不是引用)还是引用,

std::forward<T>(value)
Run Code Online (Sandbox Code Playgroud)

适合.

std::forward<T>(value)每当不知道是否T &&绑定到右值或左值时,它是正确的选择.这是这种情况,因为在构造函数中我们不知道是否T &&等效U &&于某些普通类型U,或等效于U & &&.

T在函数调用中推断是否std::forward在不同时间使用或确定(例如在您的示例中,在实例化模板T时确定的位置Node)并不重要.

std::forward<T>(value)将调用继承的构造函数,就像调用者直接调用基类构造函数一样.也就是说,当它value是一个左值时,它会在左值上调用它,而在右值时它将在左值上调用它value.


And*_*zos 1

T在你的例子中没有推导出来。是T类模板参数,而不是函数模板参数。因此,假设您不会使用引用类型作为 T,T&&它将是对 T 的右值引用,因此它只会绑定到类型 T 的右值。这些可以安全移动,因此您可以std::move在此处使用。

template<class T>
struct Node : public NodeBase<T>
{
    Node(T &&value)
        : NodeBase( std::move (value)) { }
};

int main()
{
    int i = 3;

    Node<int> x(42); // ok
    Node<int> y(std::move(i)); // ok
    Node<int> z(i); // error
}
Run Code Online (Sandbox Code Playgroud)

std::forward通常仅适用于具有推导类型的地方,该推导类型可以是左值引用或右值引用。

template<class T>
void f(T&& x)
{
    ... std::forward<T>(x) ...
}
Run Code Online (Sandbox Code Playgroud)

因为T&&实际上可能是左值引用或右值引用。这只是因为T是在这种背景下推论出来的。