2010-10-28 4 views
17

Mi piacerebbe sapere come vengono implementate le tuple nella libreria standard per C++ 0x. Ho provato a leggere description in libstdc++ manual e poi a leggere template listing, ma è davvero difficile capire come funziona, specialmente quando si legge il codice.Come viene implementata la std :: tuple?

Qualcuno potrebbe spiegarmi in poche frasi l'idea dell'implementazione della tupla? Voglio sapere questo, perché sto pensando di usare le tuple nel mio codice e voglio capire come funziona e quale tipo di overhead ci porta (estende solo il tempo di compilazione, esegue molte operazioni di copia sulla memoria, esegue molte altre funzioni nel costruttore , eccetera.).

risposta

23

Un approccio per l'implementazione di tuple è l'utilizzo dell'ereditarietà multipla. Gli elementi tuple sono tenuti da classi foglia e la stessa classe di tuple eredita da più foglie. In pseudo-codice:

template<typename T0, typename T1, ..., typename Tn> 
class PseudoTuple : TupleLeaf<0, T0>, TupleLeaf<1, T1>, ..., TupleLeaf<n, Tn> { 
    ... 
}; 

Ogni foglia ha un indice, in modo che ogni classe base diventa unico anche se i tipi di contenuti sono identici, così possiamo accedere all'ennesimo elemento con un semplice static_cast:

static_cast<TupleLeaf<0, T0>*>(this); 
// ... 
static_cast<TupleLeaf<n, Tn>*>(this); 

ho scritto una spiegazione dettagliata su questa implementazione tupla "piatta" qui: C++11 tuple implementation details (Part 1)

+0

Sì, questa è un'ottima spiegazione! Sfortunatamente, non è così che la tupla è implementata in libstdC++, che si attacca all'implementazione ricorsiva. Non vedo l'ora di distribuire una libC++ ampiamente distribuita! –

+0

Potrebbe anche essere utile descrivere brevemente anche l'implementazione non ricorsiva. –

+1

@KyleStrand erm, questo è l'implementazione non ricorsiva (T: L1, L2, L3 vs T: L1: L2: L3 dell'implementazione ricorsiva) – mitchnull

2

L'implementazione di std::tuple è possibile tramite variadic templates, che sono stati introdotti nel linguaggio principale.

So che questo sta elemosinando la domanda, ma ti dà una frase di ricerca migliore per la ricerca.

+2

Inoltre, l'implementazione * non * è banale, come dimostra il fatto che OP menzionato cercando e non riuscendo a capire da rea ding il codice di un'implementazione di esempio. –

+2

Questa risposta è in discussione [sulla meta] (http://meta.stackoverflow.com/questions/290254/for-the-question-how-is-x-implemented-is-its-trivial-using-feature-y -an-an). – Daedalus

+1

@KyleStrand l'OP legge il codice nel 2010 quando i modelli variadici non erano ancora comunemente compresi. Gli ho dato gli strumenti per capire i modelli variadici. Considero questa una risposta. – Motti

10

Una tupla viene in genere implementata come una lista concatenata di tempo di compilazione.

Il codice è un po 'offuscato attraverso template sintassi, ma seguenti elementi sono normalmente presenti:

  1. una catena di classi con elementi di testa e di coda (contro-elementi)
  2. un'istanza coda vuota a indica la fine della lista.
  3. codice ricorsivo per percorrere l'elenco a un determinato indice, implementato come istanze di modello ricorsivo (istanziato in fase di compilazione).

Esistono implementazioni ragionevoli in C++ 03 (ad es. Boost).

I modelli Variadic consentono un numero illimitato di elementi, come menzionato da Motti.

Il costo è normalmente un tempo di compilazione. I costruttori di copia potrebbero essere chiamati durante l'inizializzazione (max 1) e quando si copiano le tuple.