Recently I've discovered che a volte essere in grado di convertire i valori effettivi temporaneamente in lvalue può essere utile per me.È ben definito il cast di xvalues su lvalue per passare alle funzioni?
Sto usando il seguente strumento:
#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);
}
E 'utile quando si deve utilizzare le funzioni che richiedono lvalue come argomenti, ma non hanno alcun interesse per ciò che quei particolari valori ottengono cambiato in. Per quando sei interessato ad altri vettori di output che non sono correlati all'argomento specifico specificato.
Ad esempio, questo:
std::string get_my_file() {
std::ifstream ifs("myfile.txt");
return {std::istreambuf_iterator<char>(ifs), {}};
}
può essere modificato a questo:
std::string get_my_file() {
return {std::istreambuf_iterator<char>(lvalue(std::ifstream("myfile.txt"))),
{}};
}
E questo:
std::string temp1 = get_my_shader();
const char *temp2 = temp1.c_str();
glShaderSource(a, 1, &temp2, nullptr);
può essere modificato a questo:
glShaderSource(a, 1, &lvalue(get_my_shader().c_str()), nullptr);
e consentire cose come questa:
void foo(int *x) {
std::cout << *x << std::endl;
}
foo(&lvalue(5));
Mi piacerebbe essere sicuro se sto invocando indefinito-comportamento o non in tutto questo, perché non vedo alcuna, anche se ci possono essere qualche regola di casting che lo renderebbe illegale (che ignoro). Per quanto riguarda la durata dei provvisori, non vedo alcun problema da quando, AFAIK, rvalues live until the end of full-expression e l'utilizzo della funzione è limitato a questo.
C'è una recente modifica alla norma sulla reinterpret_cast
e xvalues
che sembra essere il tema:
https://stackoverflow.com/a/26793404/1000282
EDIT:
versione migliore con riferimento collasso come suggerito:
template <typename T>
constexpr T &lvalue(T &&r) noexcept { return r; }
Stai bene. L'unica cosa che puoi facilmente rovinare colando xvalues su lvalues è la durata, e hai ragione non c'è alcun pericolo nei tuoi esempi, dato che il temporaneo non è referenziato oltre la dichiarazione che lo crea. (La proposta 'reinterpret_cast' in realtà non tocca la tua domanda.) – Deduplicator
@Deduplicator Grazie, ho dichiarato rvalues invece di xvalue specifici, perché la domanda include anche espressioni come' & lvalue (5) '. Che tra l'altro sta funzionando bene. –
BTW: Perché usi 'std :: remove_reference_t' invece delle regole di compressione di riferimento? – Deduplicator