std :: move,std :: forward,值类型和模板推导

Zou*_*uch 3 c++ templates c++11

假设我有这个代码

template <typename T> void Swap(T&& a, T&& b) {
    T tmp = std::move(a);
    a = std::move(b);
    b = std::move(tmp);
}

int main()
{
    int a = 2;
    int b = 3;
}
Run Code Online (Sandbox Code Playgroud)

根据我对这个讲话的理解,在调用时Swap(a, b),编译器应该推断出T&&应该T&转换它的事实.但在这种情况下,GCC给了我以下错误:

error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'std::remove_reference<int&>::type {aka int}' 
T tmp = std::move(a);
Run Code Online (Sandbox Code Playgroud)

我要么必须Swap使用Swap(std::forward<int>(a), std::forward<int>(b))或调用Swap(std::move(a), std::move(b)),要么替换Swap签名Swap(T& a, T& b).

为什么会这样 ?这里的正确用法是什么?

Ker*_* SB 6

你需要这个:

template <typename T> void Swap(T&& a, T&& b)
{
    using U = typename std::remove_reference<T>::type;

    U tmp = std::move(a);
    a = std::move(b);
    b = std::move(tmp);
}
Run Code Online (Sandbox Code Playgroud)

正如您在问题中暗示的那样,在您的示例中,T推断为int&,并且初始化int& tmp = std::move(a);是错误的.

  • 打败我...... :( (2认同)