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

时间:2016-07-14 16:18:18

标签: 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;
}

根据我对this talk的理解,在调用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);

我必须使用SwapSwap(std::forward<int>(a), std::forward<int>(b))来致电Swap(std::move(a), std::move(b)),或者将Swap签名替换为Swap(T& a, T& b)

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

1 个答案:

答案 0 :(得分: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);
}

正如您在问题中所暗示的那样,在您的示例中,T被推断为int&,初始化int& tmp = std::move(a);格式不正确。