jimifiki
jimifiki

Reputation: 5534

C++ Idioms: How can an rvalue be passed around as rvalue?

The following code doesn't compile. Clang gives this error message: candidate function not viable: no known conversion from 'A' to 'A &&' for 1st argument

this is as if a inside f() were an lvalue.

struct A{};

void g(A&& a){
    return;
}

void f(A&& a){
    g(a);
}

int main(){
    return 0;
}

This is reasonable because prevent f() from calling g() more than once.

The following would fix my code:

g(std::move(a)); 

but looks wrong at me: think what happens if someone modifies the signature of f() to void f(A& a).

Is there a better idiom?

Upvotes: 3

Views: 62

Answers (1)

lubgr
lubgr

Reputation: 38267

but looks wrong at me: think what happens if someone modifies the signature of f() to void f(A& a).

Changing a function signature with respect to the value category of an argument is a breaking change that might require manual checking of every invocation of that function. You won't find a C++ idiom that magically adapts to such a change.

The "fix" g(std::move(a)) is the correct way of preserving the rvalueness of the function argument. Stick with it if g is supposed to operate on an rvalue. If you later decide that it doesn't make sense for g to accept an rvalue, but you want to pass an lvalue instead, refactor it - and adjust the invocations. In that particular case, the compiler will help you as it rejects binding an rvalue to the function argument A& a.

Upvotes: 5

Related Questions