Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::move, std::forward, value type and template deduction

Let say I have this code

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;
}

According to my understanding of this talk, when calling Swap(a, b), the compiler should deduce the fact that T&& should be T& and convert it. But in this case GCC gives me the following error :

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);

I either have to call Swap using Swap(std::forward<int>(a), std::forward<int>(b)) or Swap(std::move(a), std::move(b)), or to replace the Swap signature by Swap(T& a, T& b).

Why is that the case ? What is the correct usage here ?

like image 922
cmourglia Avatar asked Jun 02 '26 04:06

cmourglia


1 Answers

You need this:

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);
}

As you hinted at in your question, in your example, T is deduced as int&, and the initialization int& tmp = std::move(a); is ill-formed.

like image 171
Kerrek SB Avatar answered Jun 03 '26 19:06

Kerrek SB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!