tuple
in boost e TR1/C++ 0x fornisce un metodo conveniente (per il writer della funzione) per restituire due valori da una funzione - tuttavia sembra danni una delle principali caratteristiche del linguaggio per il chiamante: la capacità di utilizzare semplicemente la funzione per inizializzare una variabile:Come inizializzare con più valori di ritorno in C++ (0x)
T happy();
const auto meaningful_name(happy()); // RVO means no excess copies
ma per:
tuple<T,U> sad();
ci sia hanno a cedere la capacità di scegliere un nome significativo per i nostri valori di ritorno e utilizzare get<n>()
in tutto il mondo:
const auto two_unrelated_things(sad());
o effettuare una temporanea:
const auto unwanted_named_temporary(sad());
const auto one_name(get<0>(unwanted_named_temporary));
const auto two_name(get<1>(unwanted_named_temporary));
o passare da inizializzazione assegnazione, che funziona solo se i tipi sono assegnabili, e rompe auto
:
tuple_element<0, decltype(sad())>::type one_mutable; // there might be a less
tuple_element<1, decltype(sad())>::type two_mutable; // verbose way
tie(one_mutable,two_mutable) = sad();
o fare qualcosa di innaturale per una classe locale:
const struct ugh {
ugh(decltype(sad()) rhs) : one_name(get<0>(rhs)), two_name(get<1>(rhs)) {}
const tuple_element<0, decltype(sad())>::type one_name;
const tuple_element<1, decltype(sad())>::type two_name;
} stuff(sad()); // at least we avoid the temporary and get initialization
C'è un modo migliore? Sto usando i costrutti compatibili VC10 sopra, qualche cosa in pieno C++ 0x o aiuto di spinta?
ideale sarebbe:
- mi permette di utilizzare l'inizializzazione, non solo l'assegnazione
- lasciare che il chiamante scegliere i nomi per i
- non fare più copie restituite-in variabili
- funziona sia per le variabili stack che per i membri della classe
- potrebbe essere una grande libreria di modelli pazza, ma avere una sintassi sana per il chiamante e il writer delle funzioni
Domanda interessante, anche se non vedo come si possano definire variabili di tipi diversi in una singola espressione. - Penso che l'opzione "o fare un temporaneo" potrebbe essere OK, se cambi le variabili nominate in riferimenti (evitando di copiare). – UncleBens
Un buon punto sui riferimenti: penso che sia una soluzione per le variabili dello stack. Ho provato a fare lo stesso in una classe: class C { pubblico: C sr () (triste()), uno (ottenere <0> (SR)), due (ottenere <1> (SR)) {} const T & one; const U & two; privato: tupla sr; Ma sembra in VC10, C è due puntatori più grandi della tupla, non un grosso problema ma una specie di zoppa - non sarebbe legale per il compilatore riconoscere che i riferimenti sono alias e non allocare spazio nel caso per loro? Non è questo il motivo per cui i riferimenti ai riferimenti sono illegali in primo luogo? –
BCoates
Con una classe, se i dati sono memorizzati come una tupla, è possibile fornire solo metodi di accesso nominati, che chiamano il rispettivo 'get'. Dubito che ci sarà una soluzione basata su "modello pazzo", perché il linguaggio di base non sembra supportare quello che stai chiedendo. Forse potresti semplicemente ridurre il numero di caratteri che devi digitare con i macro ... –
UncleBens