rvalue to lvalue conversion function

827 views
Skip to first unread message

Francisco

unread,
Nov 19, 2014, 8:07:15 PM11/19/14
to std-pr...@isocpp.org
Recently I've discovered I can turn rvalues into lvalues through this template

template
<typename T> inline constexpr typename std::remove_reference<T>::type &make_ref(T &&r) noexcept { using U = typename std::remove_reference<T>::type; return static_cast<U &>(r); }

This is useful for me in the following example situation:

string get_my_file_contents() {
return {std::istreambuf_iterator<char>(make_ref(std::ifstream("my_file.txt"))),
std::istreambuf_iterator<char>()};
}

I mean, it's useful in any case where you have a function that accepts an lvalue
reference as parameter solely, but you don't want to create a temporary variable
in the scope just to pass it to a function call, so you consciously make a lvalue
out of a rvalue inside the expression.

Without this, I would have to do
:


string get_my_file_contents() {
std::ifstream temp("my_file.txt");
return {std::istreambuf_iterator<char>(temp),
std::istreambuf_iterator<char>()};
};

There's some wording added to C++14 standard about reinterpret_cast
that relates to this kind of conversion I believe, for which reasons
of inclusion I have no idea for sure.

This also make it possible to temporarily get addresses of rvalues (just to pass as
argument for example) and what not.

David Krauss

unread,
Nov 21, 2014, 6:03:32 PM11/21/14
to std-pr...@isocpp.org
On 2014–11–20, at 9:07 AM, Francisco <francisco.m...@oblita.com> wrote:

Recently I've discovered I can turn rvalues into lvalues through this template

template
<typename T> inline constexpr typename std::remove_reference<T>::type &make_ref(T &&r) noexcept { using U = typename std::remove_reference<T>::type; return static_cast<U &>(r); }
This helps to defeat the safety built into rvalue-specific interfaces. Creating such a convenience facility is your own business, but I can’t imagine a proposal gaining traction.
There's some wording added to C++14 standard about reinterpret_cast
that relates to this kind of conversion I believe, for which reasons
of inclusion I have no idea for sure.
Yes, and it was apparently controversial.
This also make it possible to temporarily get addresses of rvalues (just to pass as
argument for example) and what not.
There’s nothing reinterpret_cast can do here that static_cast together with const_cast can’t. The static_cast would need to use T const& , adding const to get the lvalue reference to bind an rvalue, and then the const_cast just removes that const to obtain the original type. Actually writing that for the sake of convenience is madness. CWG was probably (I would hope) considering some instances of tricky generic code when they (finally) accepted the change.

obl...@gmail.com

unread,
Nov 22, 2014, 10:09:20 AM11/22/14
to std-pr...@isocpp.org
Thanks for the reply David.

Also, because I thought there was a problem sending the topic since it didn't show up
for more than a day, I ended up creating a duplicate, sorry for that.

To tell the truth, even though it's quite useful for me in several instances, I have lost
interest in it gaining traction to be in the standard library. I found another person
using the same facility and named it "no_move", which is interesting since it does
just the reversal of move.
Reply all
Reply to author
Forward
0 new messages