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.
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); }
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.