Search code examples
c++move-semanticsrvalue-reference

difference between using std::move and adding 0 to the number?


I'm curious about that is there any practical difference between using std::move to convert an l-value integer to r-value, and adding a 0 to that integer? or any other neutral arithmetic operation (multiplying by 1, subtracting 0, etc).

Adding 0:

int f(int&& i){
    i++;
    return i;
}


int main(){
    int x = 43;
    f(x+0);
}

Using std::move:

#include <iostream>

int f(int&& i){
    i++;
    return i;
}


int main(){
    int x = 43;
    f(std::move(x));
}

I know we cannot perform such neutral actions on all types, but my question is specially about integral numbers not other types.


Solution

  • std::move(x) and x+0 do not do the same thing.

    The former gives you an rvalue (specifically xvalue) referring to x. The latter gives you a rvalue (specifically prvalue) which (after temporary materialization) refers to a temporary object with lifetime ending after the full-expression.

    So f(x+0); does not cause x to be modified, while f(std::move(x)) does.

    Taking a rvalue-reference to an int specifically is probably pointless. Moving and copying scalar types is exactly the same operation, so there is no benefit over just int&.

    And your function both returns the result by-value and tries to modify the argument. Typically, it should do only one of those things. If it takes a reference and modifies the argument it should either have void return value or return a reference to the argument. If it ought to return the result by-value, then it doesn't need to be passed a reference and can just take a int parameter. (It would be ok to both modify the argument and return by-value if the value returned was unrelated to the new value of the argument, e.g. as in std::exchange returning the old value of the argument.)