Instantly share code, notes, and snippets.

@oblitum /lvalue.md
Last active Dec 1, 2016

Embed
What would you like to do?
A rvalue to lvalue conversion function

#Opinions on rvalue to lvalue conversion function

Recently I've discovered that sometimes being able to turn rvalues temporarily into lvalues can be useful for me.

I've been using the following tool:

template <typename T>
constexpr T &lvalue(T &&r) noexcept { return r; }

It's useful when you have to use functions that require lvalues as arguments, but you don't have any interest in what those particular values get changed into. For when you are interested in other output vectors that are not related to the given specific argument.

For example, this:

std::string get_my_file() {
    std::ifstream ifs("myfile.txt");
    return {std::istreambuf_iterator<char>(ifs),
            std::istreambuf_iterator<char>()};
}

can be changed to this:

std::string get_my_file() {
    return {std::istreambuf_iterator<char>(lvalue(std::ifstream("myfile.txt"))),
            std::istreambuf_iterator<char>()};
}

And this:

std::string temp1 = get_my_shader();
const char *temp2 = temp1.c_str();
glShaderSource(a, 1, &temp2, nullptr);

can be changed to this:

glShaderSource(a, 1, &lvalue(get_my_shader().c_str()), nullptr);

There's a recent change to the standard about reinterpret_cast and xvalues that seems to be on topic:

http://stackoverflow.com/a/26793404/1000282

@marcodiiga

This comment has been minimized.

Copy link

marcodiiga commented Dec 1, 2016

Watch out: your code can invoke UB

struct test {
  test() {
      std::cout << "constructing" << std::endl;
  }
  ~test() {
      std::cout << "destroy" << std::endl;
  }
};
 
template <typename T>
constexpr T &lvalue(T &&r) noexcept { return r; }
 
int main()
{
  int ten = 10;
  test& ref = lvalue(test());
  std::cout << "now use" << std::endl;
  // Using ref is UB
}

it is safe to use as long as the temporaries aren't destructed until the end of the full expression and you're done dealing with them by that time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment