Хорошо ли определено приводить xvalues ​​к lvalues ​​для передачи в функции?

Недавно я обнаружил что иногда возможность превратить ценностивременно в lvalues ​​может быть полезным для меня.

Я использовал следующий инструмент:

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

Это полезно, когда вам нужно использовать функции, которые требуют lvalues ​​в качестве аргументов, но вас не интересует, во что изменяются эти конкретные значения. Когда вас интересуют другие выходные векторы, которые не связаны с данным конкретным аргументом.

Например, это:

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

можно изменить на это:

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

И это:

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

можно изменить на это:

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

И допустим такие вещи:

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

foo(&lvalue(5));

Я хотел бы быть уверен, что я вызываю неопределенное поведение или нет в любом из этого, потому что я не вижу ничего, хотя может быть какое-то правило приведения, которое сделает его незаконным (что я игнорирую). Что касается времени жизни временных, я не вижу проблем с тех пор, AFAIK,rvalues ​​живут до конца полного выражения и использование функции ограничено этим.

Есть недавнее изменение в стандарте оreinterpret_cast а такжеxvalues похоже на тему:

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

РЕДАКТИРОВАТЬ:

Лучшая версия с использованием свертывания ссылок, как предложено:

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

Ответы на вопрос(1)

Ваш ответ на вопрос