Tupel in C++
Tupel bieten eine Möglichkeit, mehrere Werte zusammenzufassen und als eine Einheit zu behandeln.
- Englische Aussprache
- tuple (C++ programming) tuːp(ə)l (v, Stephan T. Lavavej), tʌp(ə)l (v); [ˈtʰʌpɫ̩] (w), [ˈtʰupɫ̩] (w), [ˈtʰjupɫ̩] (w).
Gruppen von Werte, in denen ein bestimmter Wert mehrfach vorkommen kann und in denen die Reihenfolge einer Rolle spielt werden allgemein als Tupel bezeichnet. Beispielsweise bilden die Argumentwerte eines Aufrufs ein Tupel. Man kann ein Tupel auch als Verallgemeinerung von Gruppen wie Paar (2 Werte), Triple (3 Werte), Quadrupel (4 Werte), Quintupel (5 Werte) und so weiter ansehen.
Es gibt in C++ auch noch einen speziellen Datentyp »::std::tuple«. Man kann sich diesen wie »::std::pair« vorstellen, nur daß er auch mehr oder weniger als zwei Werte enthalten kann. (Die Argumentwerte eines Aufrufes sind kein Objekt dieses speziellen Datentyps »::std::tuple«, sie bilden nur ein Tupel im allgemeinen Sinne des Wortes Tupel!)
Erzeugung eines Tupels
main.cpp
#include <iostream>
#include <tuple>
int main()
{ ::std::tuple< ::std::string, int, double >jennifer{ "Jennifer", 1998, 168.2 }; }
Werte der Komponenten
main.cpp
#include <iostream>
#include <tuple>
int main()
{ ::std::tuple< ::std::string, int, double >jennifer{ "Jennifer", 1998, 168.2 };
::std::cout << ::std::get< 0 >( jennifer )<<
" (" << ::std::get< 1 >( jennifer ) << ") : " <<
::std::get< 2 >( jennifer )<< " cm" << '\n'; }- Protokoll
Jennifer (1998) : 168.2 cm
Fehlinitialisierung
main.cpp
#include <iostream>
#include <tuple>
int main()
{ ::std::tuple< ::std::string, int, double >tupel;
::std::cout << ::std::get< 0 >( tupel )<< '\n';
::std::cout << ::std::get< 1 >( tupel )<< '\n';
::std::cout << ::std::get< 2 >( tupel )<< '\n'; }- Protokoll
0
0
Größe
Der Ausdruck der Größe eines Tupels sieht etwas kompliziert aus, aber normalerweise benötigt man ihn nicht, weil man ja schon weiß, wie viele Komponenten ein Tupel hat, das man angelegt hat.
Man kann nicht direkt die Größe eines Tupelobjekts ermitteln, sondern nur die Größe eines Tupeltyps. Dabei ist »::std::tuple_size< ::std::tuple< ::std::string, int, double >>« eine Klasse mit einem statischen Eintrag »value«, der dann die Größe enthält.
if the qualified-id std::tuple_size<E> names a complete type, the expression std::tuple_-
size<E>::value shall be a well-formed integral constant expression and the number of elements in the
identifier-list shall be equal to the value of that expression.
main.cpp
#include <iostream>
#include <tuple>
int main()
{ ::std::cout << ::std::tuple_size< ::std::tuple< ::std::string, int, double >>::value << '\n'; }
- Protokoll
3
»::std::tuple_size_v« ist als eine Abkürzung gedacht und ergibt direkt die Größe als Wert vom Type size_t
main.cpp
#include <iostream>
#include <tuple>
int main()
{ ::std::cout << ::std::tuple_size_v< ::std::tuple< ::std::string, int, double >> << '\n'; }
- Protokoll
3
Erzeugung eines Tupels mit Typherleitung
main.cpp
#include <iostream>
#include <tuple>
#include <string> // "s
using namespace ::std::literals;
int main()
{ ::std::tuple jennifer{ "Jennifer"s, 1998, 168.2 };
::std::cout << ::std::get< 0 >( jennifer )<<
" (" << ::std::get< 1 >( jennifer ) << ") : " <<
::std::get< 2 >( jennifer )<< " cm" << '\n'; }- Protokoll
Jennifer (1998) : 168.2 cm
Erzeugung eines Tupels mit »::std::make_tuple«
main.cpp
#include <iostream>
#include <tuple>
int main()
{ ::std::tuple< ::std::string, int, double >jennifer =
::std::make_tuple( "Jennifer", 1998, 168.2 );::std::cout << ::std::get< 0 >( jennifer )<<
" (" << ::std::get< 1 >( jennifer ) << ") : " <<
::std::get< 2 >( jennifer )<< " cm" << '\n'; }- Protokoll
Jennifer (1998) : 168.2 cm
CCG: “T.44: Use function templates to deduce class template argument types (where feasible)”
Zugriffe mit Typargumenten
Die Felder mit Zahlen an Stelle von Namen sind für Datensätze nicht unbedingt die beste Lösung, aber manchmal sind Tupel doch hilfreich.
main.cpp
#include <iostream>
#include <tuple>
#include <string> // "susing namespace ::std::literals;
int main()
{ auto jennifer =
::std::make_tuple( "Jennifer"s, 1998, 168.2 );::std::cout << ::std::get< ::std::string >( jennifer )<<
" (" << ::std::get< int >( jennifer ) << ") : " <<
::std::get< double >( jennifer )<< " cm" << '\n'; }- Protokoll
Jennifer (1998) : 168.2 cm
Ein nicht-eindeutiger Typ führt zu einer Fehlermeldung beim Übersetzen.
Vergleiche von Tupel
main.cpp
#include <ios> /* ::std::boolalpha, ::std::noboolalpha */
#include <iostream>
#include <tuple>
#include <string> /* "s */using namespace ::std::literals;
int main()
{ ::std::cout << ::std::boolalpha;
auto jennifer =
::std::make_tuple( "Jennifer"s, 1998, 168.2 );auto dennis =
::std::make_tuple( "Dennis"s, 1992, 186.8 );::std::cout <<( jennifer < dennis )<< '\n'; }
- Protokoll
false
Analytische Zuweisung
main.cpp
#include <ios> /* ::std::boolalpha, ::std::noboolalpha */
#include <iostream>
#include <tuple>
#include <string> /* "s */using namespace ::std::literals;
int main()
{ ::std::cout << ::std::boolalpha;
auto jennifer =
::std::make_tuple( "Jennifer"s, 1998, 168.2 );::std::string name;
int geburtsjahr;
double groesse_in_cm;::std::tie( name, geburtsjahr, groesse_in_cm )= jennifer;
::std::cout << name << " (" << geburtsjahr << ") : " <<
groesse_in_cm << " cm" << '\n'; }- Protokoll
Jennifer (1998) : 168.2 cm
main.cpp
#include <ios> /* ::std::boolalpha, ::std::noboolalpha */
#include <iostream>
#include <tuple>
#include <string> /* "s */using namespace ::std::literals;
int main()
{ ::std::cout << ::std::boolalpha;
auto jennifer =
::std::make_tuple( "Jennifer"s, 1998, 168.2 );auto[ name, geburtsjahr, groesse_in_cm ]= jennifer;
geburtsjahr = 22;
::std::cout << ::std::get< 0 >( jennifer )<<
" (" << ::std::get< 1 >( jennifer ) << ") : " <<
::std::get< 2 >( jennifer )<< " cm" << '\n';::std::cout << name << " (" << geburtsjahr << ") : " <<
groesse_in_cm << " cm" << '\n'; }- Protokoll
Jennifer (1998) : 168.2 cm
Jennifer (22) : 168.2 cm