Ist es gut definiert, x-Werte für die Übergabe an Funktionen in l-Werte umzuwandeln?

or kurzem habe ich entdeckt, dass manchmal in der Lage sein, Werte zu drehenvorübergehenin lvalues kann für mich nützlich sein.

Ich habe das folgende Tool verwendet:

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

Es ist nützlich, wenn Sie Funktionen verwenden müssen, für die lWerte als Argumente erforderlich sind, Sie jedoch kein Interesse daran haben, in welche Werte diese Werte geändert werden. Wenn Sie an anderen Ausgabevektoren interessiert sind, die sich nicht auf das angegebene spezifische Argument beziehen.

Zum Beispiel dieses:

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

kann folgendermaßen geändert werden:

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

Und das

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

kann folgendermaßen geändert werden:

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

Und erlaube Dinge wie diese:

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

foo(&lvalue(5));

Ich möchte sichergehen, ob ich undefined-behaviour aufrufe oder nicht, weil ich keine sehe, obwohl es vielleicht eine Casting-Regel gibt, die es illegal macht (die ich ignoriere). In Bezug auf die Lebensdauer von Provisorien sehe ich kein Problem, da, AFAIK,rWerte bleiben bis zum Ende des vollständigen Ausdrucks erhalten und die Verwendung der Funktion ist darauf beschränkt.

Es gibt eine kürzlich erfolgte Änderung des Standards fürreinterpret_cast undxvalues das scheint zum Thema zu gehören:

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

BEARBEITE:

Bessere Version unter Verwendung der Referenz, die wie vorgeschlagen reduziert wird:

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

Antworten auf die Frage(2)

Ihre Antwort auf die Frage