+ 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

11th May 2022, 3:31 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
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.
11th May 2022, 5:18 PM
OrHy3
OrHy3 - avatar
+ 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.
11th May 2022, 7:53 PM
OrHy3
OrHy3 - avatar
+ 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
12th May 2022, 3:40 AM
XXX
XXX - avatar
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🤷‍♂️
11th May 2022, 4:41 PM
OrHy3
OrHy3 - avatar
0
Also found out that std::move works, but only on base types (as far as I tested)
11th May 2022, 4:48 PM
OrHy3
OrHy3 - avatar
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 ?
11th May 2022, 4:54 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
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
11th May 2022, 6:08 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
0
Thanks OrHy3 nd XXX
12th May 2022, 7:28 AM
Ketan Lalcheta
Ketan Lalcheta - avatar