Why is an rvalue link passed as an lvalue link?

pass() and pass it to reference , however the rvalue argument, actually called reference(int&) instead of reference(int &&) , is my code snippet:

 #include <iostream> #include <utility> void reference(int& v) { std::cout << "lvalue" << std::endl; } void reference(int&& v) { std::cout << "rvalue" << std::endl; } template <typename T> void pass(T&& v) { reference(v); } int main() { std::cout << "rvalue pass:"; pass(1); std::cout << "lvalue pass:"; int p = 1; pass(p); return 0; } 

output:

 rvalue pass:lvalue lvalue pass:lvalue 

For p this is easy to understand according to the rule for dropping links , but why does the template function go from v to reference() as an lvalue?

+5
source share
2 answers
 template <typename T> void pass(T&& v) { reference(v); } 

You use the forwarding link here pretty well, but the fact that there is now the name v , he considered lvalue reference to rvalue.

Simply put, all that has a name is an lvalue . That's why Perfect Forwarding is needed to get the full semantics, use std::forward

 template <typename T> void pass(T&& v) { reference(std::forward<T>(v)); } 

What std::forward<T> does is just do something like this

 template <typename T> void pass(T&& v) { reference(static_cast<T&&>(v)); } 

See this ;

+7
source

Why does the template function pass v to reference() as an lvalue?

This is because v is an lvalue. What to expect? v is an rvalue reference . The important thing is that this is a link, and therefore an lvalue. It doesn't matter that it only binds to rvalues.

If you want to keep a category of values, you will need to make the perfect shipment. Perfect forwarding means that if you pass an rvalue (for example, in your case), the function will be called with rvalue (instead of lvalue):

 template <typename T> void pass(T&& v) { reference(std::forward<T>(v)); //forward 'v' to 'reference' } 
+7
source

All Articles