2010-10-28 23 views
17

Chciałbym wiedzieć, w jaki sposób są tuple zaimplementowane w standardowej bibliotece dla C++ 0x. Próbowałem przeczytać description in libstdc++ manual, a następnie przeczytać template listing, ale naprawdę trudno jest zrozumieć, jak to działa, szczególnie podczas czytania kodu.W jaki sposób wdraża się std :: tuple?

Czy ktoś może wyjaśnić mi w kilku zdaniach ideę implementacji krotki? Chcę to wiedzieć, ponieważ myślę o używaniu krotek w moim kodzie i chcę zrozumieć, jak to działa i jaki ma na sobie narzut (rozszerza tylko czas kompilacji, wykonuje wiele operacji kopiowania w pamięci, wykonuje wiele innych funkcji w konstruktorze itp.).

Odpowiedz

23

Jednym ze sposobów wdrażania krotek jest dziedziczenie wielokrotne. Krotki elementy są przechowywane przez klasy liści, a klasa krotka sama dziedziczy z wielu listków. W pseudo-kod:

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

Każdy liść ma indeks, tak aby każda baza klasy staje się wyjątkowa, nawet jeśli rodzaje nich zawarte są identyczne, dzięki czemu możemy uzyskać dostęp do ntą element z prostego static_cast:

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

pisałem szczegółowego wyjaśnienia na temat tego „płaskiego” wdrożenie krotki tutaj: C++11 tuple implementation details (Part 1)

+0

Tak, to świetne wyjaśnienie! Niestety, nie jest tak, w jaki sposób krotka jest zaimplementowana do libstdC++, która przylega do rekurencyjnej implementacji. Nie można czekać na bardziej rozproszoną bibliotekę libC++! –

+0

Przydałoby się również krótko opisać implementację nierekurencyjną. –

+1

@KyleStrand erm, to _jest_ implementacją nierekurencyjną (T: L1, L2, L3 vs T: L1: L2: L3 implementacji rekursywnej) – mitchnull

2

Implementacja std::tuple jest możliwa przez variadic templates, które zostały wprowadzone do języka podstawowego.

Wiem, że to jest pytanie, ale daje lepsze wyszukiwanie frazy do badań.

+2

Plus, realizacja * nie * jest trywialne, o czym świadczy fakt, że OP wymienionego stara i nie rozumiejąc to przez rea ding kodu przykładowej implementacji. –

+2

Ta odpowiedź jest obecnie przedmiotem dyskusji [na temat 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 OP przeczytał kod w 2010 roku, gdy szablony variadic nie były jeszcze powszechnie rozumiane. Dałem mu narzędzia do zrozumienia szablonów variadic. Uważam, że jest to odpowiedź. – Motti

10

Krotka jest zazwyczaj zaimplementowana jako lista połączonych w czasie kompilacji.

Kod jest nieco zaciemniony przez szablon składni, ale poniżej elementy są normalnie obecne:

  1. łańcuch klas z przednich i tylnych elementów (przeciw-elements)
  2. pusty instancji ogona wskazać koniec listy.
  3. kod rekursywny służący do przejścia listy do określonego indeksu, zaimplementowanej jako rekursywne aplikacje szablonowe (tworzone w czasie kompilacji).

Istnieją rozsądne implementacje w C++ 03 (na przykład doładowanie).

Szablony w wariatów pozwalają na nieograniczoną liczbę elementów, o czym wspomniał Motti.

Koszt jest zwykle czasem kompilacji. Kopiowanie konstruktorów może zostać wywołane podczas inicjalizacji (max 1) i podczas kopiowania samych krotek.

Powiązane problemy