É bem definido converter xvalues em lvalues para passar para funções?

Recentemente eu descobri que às vezes é capaz de transformar valorestemporariamente em lvalues pode ser útil para mim.

Eu tenho usado a seguinte ferramenta:

#include <type_traits>

template <typename T>
inline constexpr std::remove_reference_t<T> &lvalue(T &&r) noexcept {
    return static_cast<std::remove_reference_t<T> &>(r);
}

É útil quando você precisa usar funções que exijam lvalues como argumentos, mas não tem interesse em saber em que esses valores específicos são alterados. Para quando você estiver interessado em outros vetores de saída que não estejam relacionados ao argumento específico fornecido.

Por exemplo, isto:

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

pode ser alterado para isso:

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

E isto:

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

pode ser alterado para isso:

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

E permita coisas como esta:

void foo(int *x) {
    std::cout << *x << std::endl;
}

foo(&lvalue(5));

Eu gostaria de ter certeza se estou invocando um comportamento indefinido ou não em nada disso, porque não vejo nenhum, embora possa haver alguma regra de elenco que a torne ilegal (o que eu ignoro). Em relação à vida útil dos temporários, não vejo problema desde que, AFAIK,Os valores permanecem até o final da expressão completa e o uso da função é restrito a isso.

Há uma mudança recente no padrão sobrereinterpret_cast exvalues que parece estar no tópico:

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

EDITAR:

Versão melhor usando o recolhimento de referência, conforme sugerido:

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

questionAnswers(1)

yourAnswerToTheQuestion