+ 1
How to pass rvalue reference in template function
Refer code below : I am calling template function as lvalue and rvalue reference, why it is not printing different type name for T from template function? From main function, type info is proper for lvalue and rvalue.. So , is it like we can't have rvalue into template function? https://code.sololearn.com/c878S8DjXGnr/?ref=app
8 ответов
+ 1
Sorry turned out I was wrong (probably seen wrong output), seems like std::move() serves as "value extractor" to do things like:
int a = (some value);
int &&b = std::move(a); //Doesn't throw error
However this turns b into a simple reference, making it useless.
In the case "int &&b = (value)" instead b turns in a simple variable after declaration. I can only deduce that lvalue references are meant to work as a sort of "constexpr" for function arguments (if we don't take care of "std::move" chance).
Sorry, I'm out of ideas.
+ 1
If you specify the template argument (having then "display<S&&>(S())"), this will do it:
template<typename T>
void display(T t) {
cout << is_rvalue_reference<T>::value << endl;
}
S() is of type S, in "S &&ref = S()" ref is instead of type rvalue reference, and if you remove the argument "t" from display() you could call "display<decltype(ref)>()" and have it work.
If you pass a variable as argument, the type deduced won't be a rvalue reference no matter what, so you have to rely on the template argument.
Last thing: found out that SL compiler's typeid() doesn't make distinctions between literals and rvalue references.
+ 1
Having a template parameter as argument in a function strips off its references (ecause if didn't, there would be no way to specify that you want a 'value' as argument to the function, and not a reference). This is why your `obj` variable is copied instead of being passed as reference and why you don't see the difference in types.
For this reason, to get a lvalue reference, you need to declare the function as
template <class T>
void display(T& t);
and T&& instead of T& when you want a rvalue reference.
If you want to recieve both lvalue and rvalue references in the function and have different values of T for them, you need to use forwarding references.
https://en.cppreference.com/w/cpp/language/reference#Forwarding_references
This blog might be helpful
https://bajamircea.github.io/coding/cpp/2016/04/07/move-forward.html
Here is a demonstration. Note how the value of T changes to T& when a lvalue reference is passed
https://code.sololearn.com/cujt1Tl0711f/?ref=app
0
Seems like so. To make it work I would try make it a macro-function, like the old C library functions that couldn't use templates:
void display(string s) {
cout << s << endl;
}
#define display(s) display(typeid(s).name())
This is the only way I know to do what you want to implement🤷♂️
0
Also found out that std::move works, but only on base types (as far as I tested)
0
Thanks OrHy3
Macro would not work for me as I just don't want to print typeid string. I need to perform other operation but was just tasting why rvalue is not captured there in template.
Regarding move , I tried below but none of these works for me:
display(move(obj));
int a;
display(a);
display(move(a));
Could you please let me know bit more to make it work with move ?
0
No problem...thanks for sharing your views.
One thing i am aware is move just transfer ownership from a to b in your case... It don't copy a to b but transfers ownership and b don't become rvalue as b is still valid post that code line, b can't be rvalue