Namespaces
Variants

std::tuple<Types...>::tuple

Aus de.cppreference.net
 
 
Dienstprogrammbibliothek
Sprachunterstützung
Typunterstützung (grundlegende Typen, RTTI)
Bibliotheks-Feature-Test-Makros (C++20)
Programm-Dienstprogramme
Variadische Funktionen
Koroutinen-Unterstützung (C++20)
Vertragsunterstützung (C++26)
Drei-Wege-Vergleich
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Allgemeine Dienstprogramme
Relationale Operatoren (veraltet in C++20)
Ganzzahl-Vergleichsfunktionen
(C++20)(C++20)(C++20)    
(C++20)
Swap und Typoperationen
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Allgemeine Vokabular-Typen
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
 
Definiert in Header <tuple>
constexpr tuple();
(1) (seit C++11)
(bedingt explizit)
tuple( const Types&... args );
(2) (seit C++11)
(constexpr seit C++14)
(bedingt explizit)
template< class... UTypes >
tuple( UTypes&&... args );
(3) (seit C++11)
(constexpr seit C++14)
(bedingt explizit)
template< class... UTypes >
constexpr tuple( tuple<UTypes...>& other );
(4) (seit C++23)
(bedingt explizit)
template< class... UTypes >
tuple( const tuple<UTypes...>& other );
(5) (seit C++11)
(constexpr seit C++14)
(bedingt explizit)
template< class... UTypes >
tuple( tuple<UTypes...>&& other );
(6) (seit C++11)
(constexpr seit C++14)
(bedingt explizit)
template< class... UTypes >
constexpr tuple( const tuple<UTypes...>&& other );
(7) (seit C++23)
(bedingt explizit)
template< class U1, class U2 >
constexpr tuple( std::pair<U1, U2>& p );
(8) (seit C++23)
(bedingt explizit)
template< class U1, class U2 >
tuple( const std::pair<U1, U2>& p );
(9) (seit C++11)
(constexpr seit C++14)
(bedingt explizit)
template< class U1, class U2 >
tuple( std::pair<U1, U2>&& p );
(10) (seit C++11)
(constexpr seit C++14)
(bedingt explizit)
template< class U1, class U2 >
constexpr tuple( const std::pair<U1, U2>&& p );
(11) (seit C++23)
(bedingt explizit)
template< tuple-like UTuple >
constexpr tuple( UTuple&& u );
(12) (seit C++23)
(bedingt explizit)
tuple( const tuple& other ) = default;
(13) (seit C++11)
tuple( tuple&& other ) = default;
(14) (seit C++11)
Allokator-erweiterte Konstruktoren
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a );
(15) (seit C++11)
(constexpr seit C++20)
(bedingt explizit)
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a,
       const Types&... args );
(16) (seit C++11)
(constexpr seit C++20)
(bedingt explizit)
template< class Alloc, class... UTypes >
tuple( std::allocator_arg_t, const Alloc& a,
       UTypes&&... args );
(17) (seit C++11)
(constexpr seit C++20)
(bedingt explizit)
template< class Alloc, class... UTypes >
constexpr tuple( std::allocator_arg_t, const Alloc& a,
                 tuple<UTypes...>& other );
(18) (seit C++23)
(bedingt explizit)
template< class Alloc, class... UTypes >
tuple( std::allocator_arg_t, const Alloc& a,
       const tuple<UTypes...>& other );
(19) (seit C++11)
(constexpr seit C++20)
(bedingt explizit)
template< class Alloc, class... UTypes >
tuple( std::allocator_arg_t, const Alloc& a,
       tuple<UTypes...>&& other );
(20) (seit C++11)
(constexpr seit C++20)
(bedingt explizit)
template< class Alloc, class... UTypes >
constexpr tuple( std::allocator_arg_t, const Alloc& a,
                 const tuple<UTypes...>&& other );
(21) (seit C++23)
(bedingt explizit)
template< class Alloc, class U1, class U2 >
constexpr tuple( std::allocator_arg_t, const Alloc& a,
                 std::pair<U1, U2>& p );
(22) (seit C++23)
(bedingt explizit)
template< class Alloc, class U1, class U2 >
tuple( std::allocator_arg_t, const Alloc& a,
       const std::pair<U1, U2>& p );
(23) (seit C++11)
(constexpr seit C++20)
(bedingt explizit)
template< class Alloc, class U1, class U2 >
tuple( std::allocator_arg_t, const Alloc& a,
       std::pair<U1, U2>&& p );
(24) (seit C++11)
(constexpr seit C++20)
(bedingt explizit)
template< class Alloc, class U1, class U2 >
constexpr tuple( std::allocator_arg_t, const Alloc& a,
                 const std::pair<U1, U2>&& p );
(25) (seit C++23)
(bedingt explizit)
template< class Alloc, tuple-like UTuple >
constexpr tuple( std::allocator_arg_t, const Alloc& a, UTuple&& u );
(26) (seit C++23)
(bedingt explizit)
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a,
       const tuple& other );
(27) (seit C++11)
(constexpr seit C++20)
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a,
       tuple&& other );
(28) (seit C++11)
(constexpr seit C++20)

Erstellt ein neues tuple.

In den folgenden Beschreibungen sei

  • i im Bereich [0, sizeof...(Types)) der Reihe nach,
  • Ti der ite Typ in Types, und
  • Ui der ite Typ in einem Template-Parameterpack namens UTypes,

wobei die Indizierung nullbasiert ist.

1) Standardkonstruktor. Wertinitialisiert alle Elemente, falls vorhanden. Der Standardkonstruktor ist trivial, wenn sizeof...(Types) == 0.
  • Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn std::is_default_constructible<Ti>::value für alle true ist i.
  • Der Konstruktor ist explicit genau dann, wenn Ti für mindestens ein {} nicht kopierinitialisierbar aus i ist.
2) Direktkonstruktor. Initialisiert jedes Element des tuple mit dem entsprechenden Parameter.
  • Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn sizeof...(Types) >= 1 und std::is_copy_constructible<Ti>::value für alle true ist i.
  • Dieser Konstruktor ist explicit genau dann, wenn std::is_convertible<const Ti&, Ti>::value für mindestens ein false ist i.
3) Konvertierungskonstruktor. Initialisiert jedes Element des tuple mit dem entsprechenden Wert in std::forward<UTypes>(args).
  • Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn
    • sizeof...(Types) == sizeof...(UTypes),
    • sizeof...(Types) >= 1,
    • std::is_constructible<Ti, Ui>::value für alle true ist i, und
    • sei D = std::decay<U0>::type(bis C++20)std::remove_cvref_t<U0>(seit C++20),
      • wenn sizeof...(Types) == 1, dann ist D nicht std::tuple, andernfalls,
      • wenn sizeof...(Types) == 2 oder sizeof...(Types) == 3, dann ist entweder D nicht std::allocator_arg_t, oder T0 ist std::allocator_arg_t.
  • Der Konstruktor ist explicit genau dann, wenn std::is_convertible<Ui, Ti>::value für mindestens ein false ist i.
(seit C++23)
4-7) Konvertierungskonstruktor. Initialisiert jedes Element des tuple mit dem entsprechenden Element von other.

Formal sei FWD(other) = std::forward<decltype(other)>(other), für alle i initialisiert das ite Element des tuple mit std::get<i>(FWD(other)).

  • Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn
    • sizeof...(Types) == sizeof...(UTypes),
    • std::is_constructible_v<Ti, decltype(std::get<i>(FWD(other)))> für alle true ist i, und
    • entweder
      • sizeof...(Types) nicht 1 ist, oder
      • (wenn Types... zu T expandiert und UTypes... zu U expandiert) std::is_convertible_v<decltype(other), T>, std::is_constructible_v<T, decltype(other)> und std::is_same_v<T, U> alle false sind.
  • Diese Konstruktoren sind explicit genau dann, wenn std::is_convertible_v<decltype(std::get<i>(FWD(other))), Ti> für mindestens ein false ist i.
  • Diese Konstruktoren sind als gelöscht definiert, wenn die Initialisierung eines Elements, das eine Referenz ist, es an ein temporäres Objekt binden würde.
(seit C++23)
8-11) Paarkonstruktor. Erstellt ein 2-Element-tuple, bei dem jedes Element aus dem entsprechenden Element von p konstruiert wird.

Formal sei FWD(p) = std::forward<decltype(p)>(p), initialisiert das erste Element mit std::get<0>(FWD(p)) und das zweite Element mit std::get<1>(FWD(p)).

  • Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn
    • sizeof...(Types) == 2,
    • std::is_constructible_v<T0, decltype(std::get<0>(FWD(p)))> = true, und
    • std::is_constructible_v<T1, decltype(std::get<1>(FWD(p)))> = true ist.
  • Der Konstruktor ist explicit genau dann, wenn std::is_convertible_v<decltype(std::get<0>(FWD(p))), T0> oder std::is_convertible_v<decltype(std::get<1>(FWD(p))), T1> = false ist.
  • Diese Konstruktoren sind als gelöscht definiert, wenn die Initialisierung eines Elements, das eine Referenz ist, es an ein temporäres Objekt binden würde.
(seit C++23)
12) tuple-like Konstruktor. Erstellt ein tuple, bei dem jedes Element aus dem entsprechenden Element von u konstruiert wird.

Formal, für alle i, initialisiert das ite Element des tuple mit std::get<i>(std::forward<UTuple>(u)).

  • Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn
    • std::same_as<std::remove_cvref_t<UTuple>, std::tuple> = false ist,
    • std::remove_cvref_t<UTuple> keine Spezialisierung von std::ranges::subrange ist,
    • sizeof...(Types) = std::tuple_size_v<std::remove_cvref_t<UTuple>> ist,
    • std::is_constructible_v<Ti, decltype(std::get<i>(std::forward<UTuple>(u)))> für alle true ist i, und
    • entweder
      • sizeof...(Types) nicht 1 ist, oder
      • (wenn Types... zu T expandiert) std::is_convertible_v<UTuple, T> und std::is_constructible_v<T, UTuple> beide false sind.
  • Dieser Konstruktor ist als gelöscht definiert, wenn die Initialisierung eines Elements, das eine Referenz ist, es an ein temporäres Objekt binden würde.
13) Implizit definierter Kopierkonstruktor. Initialisiert jedes Element des tuple mit dem entsprechenden Element von other.
  • Dieser Konstruktor ist constexpr, wenn jede von ihm ausgeführte Operation constexpr ist. Für das leere tuple std::tuple<> ist er constexpr.
  • std::is_copy_constructible<Ti>::value muss für alle true = i sein, andernfalls ist das Verhalten undefiniert(bis C++20)ist das Programm fehlerhaft(seit C++20).
14) Implizit definierter Verschiebekonstruktor. Für alle i initialisiert das ite Element des tuple mit std::forward<Ui>(std::get<i>(other)).
  • Dieser Konstruktor ist constexpr, wenn jede von ihm ausgeführte Operation constexpr ist. Für das leere tuple std::tuple<> ist er constexpr.
  • std::is_move_constructible<Ti>::value muss für alle true = i sein, andernfalls ist das Verhalten undefiniert(bis C++20)nimmt diese Überladung nicht an der Überladungsauflösung teil(seit C++20).
15-28) Identisch zu (1-14) mit der Ausnahme, dass jedes Element durch Verwende-Allokator-Konstruktion erstellt wird, d. h. das Allokatorobjekt a wird als zusätzliches Argument an den Konstruktor jedes Elements übergeben, für das std::uses_allocator<Ui, Alloc>::value = true ist.

Parameter

args - Werte zur Initialisierung jedes Elements des Tupels
other - das Tupel von Werten zur Initialisierung jedes Elements des Tupels
p - das Paar von Werten zur Initialisierung beider Elemente des 2-Tupels
u - das tuple-like Objekt von Werten zur Initialisierung jedes Elements des Tupels
a - der Allokator für die Uses-Allocator-Konstruktion

Hinweise

Bedingt explizite Konstruktoren ermöglichen die Konstruktion eines Tupels im Copy-Initialisierungskontext unter Verwendung der Listeninitialisierungssyntax:

std::tuple<int, int> foo_tuple() 
{
    // return {1, -1};             // Fehler vor N4387
    return std::make_tuple(1, -1); // Funktioniert immer
}

Beachten Sie, dass wenn ein Element der Liste nicht implizit in das entsprechende Element des Ziel-Tupels konvertierbar ist, die Konstruktoren explizit werden:

using namespace std::chrono;
void launch_rocket_at(std::tuple<hours, minutes, seconds>);
launch_rocket_at({hours(1), minutes(2), seconds(3)}); // OK
launch_rocket_at({1, 2, 3}); // Fehler: int ist nicht implizit in duration konvertierbar
launch_rocket_at(std::tuple<hours, minutes, seconds>{1, 2, 3}); // OK

Beispiel

#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <vector>
// Hilfsfunktion zum Ausgeben eines Vektors in einen Stream
template<class Os, class T>
Os& operator<<(Os& os, std::vector<T> const& v)
{
    os << '{';
    for (auto i{v.size()}; const T& e : v)
        os << e << (--i ? "," : "");
    return os << '}';
}
template<class T>
void print_single(T const& v)
{
    if constexpr (std::is_same_v<T, std::decay_t<std::string>>)
        std::cout << std::quoted(v);
    else if constexpr (std::is_same_v<std::decay_t<T>, char>)
        std::cout << "'" << v << "'";
    else
        std::cout << v;
}
// Hilfsfunktion zum Ausgeben eines Tupels beliebiger Größe
template<class Tuple, std::size_t N>
struct TuplePrinter
{
    static void print(const Tuple& t)
    {
        TuplePrinter<Tuple, N - 1>::print(t);
        std::cout << ", ";
        print_single(std::get<N - 1>(t));
    }
};
template<class Tuple>
struct TuplePrinter<Tuple, 1>
{
    static void print(const Tuple& t)
    {
        print_single(std::get<0>(t));
    }
};
template<class... Args>
void print(std::string_view message, const std::tuple<Args...>& t)
{
    std::cout << message << " (";
    TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
    std::cout << ")\n";
}
// Ende der Hilfsfunktion
int main()
{
    std::tuple

(Keine Übersetzung erforderlich, da der Text innerhalb der HTML-Tags gemäß den Anweisungen beibehalten wird und keine zu übersetzenden Inhalte außerhalb der Tags vorhanden sind)<int, std::string, double> t1;
    print("Wertinitialisiert, t1:", t1);
    std::tuple<int, std::string, double> t2{42, "Test", -3.14};
    print("Mit Werten initialisiert, t2:", t2);
    std::tuple<char, std::string, int> t3{t2};
    print("Implizit konvertiert, t3:", t3);
    std::tuple<int, double> t4{std::make_pair(42, 3.14)};
    print("Konstruiert aus einem Paar, t4:", t4);
    // gegeben Allocator my_alloc mit einem Single-Argument-Konstruktor
    // my_alloc(int); verwenden Sie my_alloc(1), um 5 ints in einem Vektor zu allokieren
    using my_alloc = std::allocator<int>;
    std::vector<int, my_alloc> v{5, 1, my_alloc{/* 1 */}};
    // verwende my_alloc(2) um 5 ints in einem Vektor in einem Tupel zu allozieren
    std::tuple<int, std::vector<int, my_alloc>, double> t5
        {std::allocator_arg, my_alloc{/* 2 */}, 42, v, -3.14};
    print("Konstruiert mit Allokator, t5:", t5);
}

Mögliche Ausgabe:

Wertinitialisiert, t1: (0, "", 0)
Mit Werten initialisiert, t2: (42, "Test", -3.14)
Implizit konvertiert, t3: ('*', "Test", -3)
Aus einem Paar konstruiert, t4: (42, 3.14)
Mit Allokator konstruiert, t5: (42, {1,1,1,1,1}, -3.14)

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 2510 C++11 Standardkonstruktor war implizit bedingt-explizit gemacht
LWG 3121 C++11 Konstruktor von 1-Tupel könnte Einschränkungen rekursiv prüfen;
allocator_arg_t Argument brachte Mehrdeutigkeit
weiter eingeschränkt
der Konstruktor
LWG 3158 C++11 der uses-allocator Konstruktor entsprechend
dem Standardkonstruktor war implizit
bedingt-explizit gemacht
LWG 3211 C++11 ob der Standardkonstruktor von
tuple<> trivial war, war nicht spezifiziert
muss trivial sein
LWG 4045 C++23 tuple-like Konstruktor könnte möglicherweise hängende Referenzen erzeugen als gelöscht definiert
N4387 C++11 einige Konstruktoren waren explizit, was nützliches Verhalten verhinderte die meisten Konstruktoren
bedingt-explizit gemacht

Siehe auch

weist die Inhalte eines tuple einem anderen zu
(öffentliche Elementfunktion)
(C++11)
erstellt ein tuple -Objekt des durch die Argumenttypen definierten Typs
(Funktionstemplate)
(C++11)
erstellt ein tuple aus Lvalue-Referenzen oder entpackt ein tuple in einzelne Objekte
(Funktionstemplate)
erstellt ein tuple aus Forwarding-Referenzen
(Funktionstemplate)
konstruiert ein neues pair
(öffentliche Elementfunktion von std::pair<T1,T2> )