std::tuple<Types...>::tuple
| 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
iim Bereich[0,sizeof...(Types))der Reihe nach,Tiderite Typ inTypes, undUiderite Typ in einem Template-Parameterpack namensUTypes,
wobei die Indizierung nullbasiert ist.
sizeof...(Types) == 0.
- Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn
std::is_default_constructible<Ti>::valuefür alletrueisti. - Der Konstruktor ist
explicitgenau dann, wennTifür mindestens ein{}nicht kopierinitialisierbar ausiist.
- Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn
sizeof...(Types) >= 1undstd::is_copy_constructible<Ti>::valuefür alletrueisti. - Dieser Konstruktor ist
explicitgenau dann, wennstd::is_convertible<const Ti&, Ti>::valuefür mindestens einfalseisti.
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>::valuefür alletrueisti, und- sei
D=std::decay<U0>::type(bis C++20)std::remove_cvref_t<U0>(seit C++20),- wenn
sizeof...(Types) == 1, dann istDnichtstd::tuple, andernfalls, - wenn
sizeof...(Types) == 2odersizeof...(Types) == 3, dann ist entwederDnicht std::allocator_arg_t, oderT0ist std::allocator_arg_t.
- wenn
- Der Konstruktor ist
explicitgenau dann, wennstd::is_convertible<Ui, Ti>::valuefür mindestens einfalseisti.
|
(seit C++23) |
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 alletrueisti, und- entweder
sizeof...(Types)nicht1ist, oder- (wenn
Types...zuTexpandiert undUTypes...zuUexpandiert)std::is_convertible_v<decltype(other), T>,std::is_constructible_v<T, decltype(other)>undstd::is_same_v<T, U>allefalsesind.
- Diese Konstruktoren sind
explicitgenau dann, wennstd::is_convertible_v<decltype(std::get<i>(FWD(other))), Ti>für mindestens einfalseisti.
|
(seit C++23) |
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, undstd::is_constructible_v<T1, decltype(std::get<1>(FWD(p)))>=trueist.
- Der Konstruktor ist
explicitgenau dann, wennstd::is_convertible_v<decltype(std::get<0>(FWD(p))), T0>oderstd::is_convertible_v<decltype(std::get<1>(FWD(p))), T1>=falseist.
|
(seit C++23) |
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>=falseist,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 alletrueisti, und- entweder
sizeof...(Types)nicht1ist, oder- (wenn
Types...zuTexpandiert)std::is_convertible_v<UTuple, T>undstd::is_constructible_v<T, UTuple>beidefalsesind.
- 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.
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>::valuemuss für alletrue=isein, andernfalls ist das Verhalten undefiniert(bis C++20)ist das Programm fehlerhaft(seit C++20).
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>::valuemuss für alletrue=isein, andernfalls ist das Verhalten undefiniert(bis C++20)nimmt diese Überladung nicht an der Überladungsauflösung teil(seit C++20).
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) |
|
(C++11)
|
erstellt ein
tuple
aus
Forwarding-Referenzen
(Funktionstemplate) |
konstruiert ein neues
pair
(öffentliche Elementfunktion von
std::pair<T1,T2>
)
|