std::tuple<Types...>:: tuple
|
Definiert im 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,
|
(16) |
(seit C++11)
(constexpr seit C++20) (bedingt explizit) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(17) |
(seit C++11)
(constexpr seit C++20) (bedingt explizit) |
|
template
<
class
Alloc,
class
...
UTypes
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(18) |
(seit C++23)
(bedingt explizit) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(19) |
(seit C++11)
(constexpr seit C++20) (bedingt explizit) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(20) |
(seit C++11)
(constexpr seit C++20) (bedingt explizit) |
|
template
<
class
Alloc,
class
...
UTypes
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(21) |
(seit C++23)
(bedingt explizit) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(22) |
(seit C++23)
(bedingt explizit) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(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,
|
(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,
|
(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,
|
(27) |
(seit C++11)
(constexpr seit C++20) |
|
template
<
class
Alloc
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(28) |
(seit C++11)
(constexpr seit C++20) |
Konstruiert ein neues Tupel.
In den folgenden Beschreibungen sei
-
i
liegt im Bereich
[ 0 ,sizeof... ( Types ))in aufsteigender Reihenfolge, -
Tisei deri-te Typ inTypes, und -
Uisei deri-te Typ in einem Template-Parameterpaket namensUTypes,
wobei die Indizierung nullbasiert ist.
- Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn std:: is_default_constructible < Ti > :: value für alle i true ist.
-
Der Konstruktor ist
explicit
genau dann, wenn
Tifür mindestens ein i nicht copy-list-initializable von { } ist.
- Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn sizeof... ( Types ) >= 1 und std:: is_copy_constructible < Ti > :: value für alle i true ist.
- Dieser Konstruktor ist explicit genau dann, wenn std:: is_convertible < const Ti & , Ti > :: value für mindestens ein i false ist.
-
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn
- sizeof... ( Types ) == sizeof... ( UTypes ) ,
- sizeof... ( Types ) >= 1 ,
- std:: is_constructible < Ti, Ui > :: value für alle i true ist, und
-
sei
Ddefiniert als std:: decay < U0 > :: type (bis C++20) std:: remove_cvref_t < U0 > (seit C++20) ,-
wenn
sizeof...
(
Types
)
==
1
, dann ist
Dnichtstd::tuple, andernfalls, -
wenn
sizeof...
(
Types
)
==
2
oder
sizeof...
(
Types
)
==
3
, dann ist entweder
Dnicht std::allocator_arg_t , oderT0ist std::allocator_arg_t .
-
wenn
sizeof...
(
Types
)
==
1
, dann ist
- Der Konstruktor ist explicit genau dann, wenn std:: is_convertible < Ui, Ti > :: value für mindestens ein i false ist.
|
(seit C++23) |
Formal sei
FWD
(
other
)
definiert als
std::
forward
<
decltype
(
other
)
>
(
other
)
. Für alle
i
initialisiert er das
i
-te Element des Tupels 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 i true ist, und
-
entweder
- sizeof... ( Types ) nicht 1 ist, oder
-
(wenn
Types...zuTexpandiert undUTypes...zuUexpandiert) 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 i false ist.
|
(seit C++23) |
Formal sei FWD ( p ) definiert als 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 dann an der Überladungsauflösung teil, wenn
- sizeof... ( Types ) == 2 ,
- std:: is_constructible_v < T0, decltype ( std :: get < 0 > ( FWD ( p ) ) ) > gleich true ist, und
- std:: is_constructible_v < T1, decltype ( std :: get < 1 > ( FWD ( p ) ) ) > gleich 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 > gleich false ist.
|
(seit C++23) |
tuple-like
Konstruktor. Konstruiert ein Tupel, wobei jedes Element aus dem entsprechenden Element von
u
konstruiert wird.
Formal initialisiert für alle
i
das
i
-te Element des Tupels mit
std
::
get
<
i
>
(
std::
forward
<
UTuple
>
(
u
)
)
.
-
Diese Überladung nimmt nur dann 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 ) gleich 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
i
trueist, und -
entweder
- sizeof... ( Types ) nicht 1 ist, oder
-
(wenn
Types...zuTexpandiert) std:: is_convertible_v < UTuple, T > und std:: is_constructible_v < T, UTuple > beidefalsesind.
-
std::
same_as
<
std::
remove_cvref_t
<
UTuple
>
,
std::
tuple
>
- Dieser Konstruktor ist als gelöscht definiert, wenn die Initialisierung eines Referenzelements dieses an ein temporäres Objekt binden würde.
- Dieser Konstruktor ist constexpr , wenn jede durchgeführte Operation constexpr ist. Für das leere Tupel std:: tuple <> ist es constexpr .
- std:: is_copy_constructible < Ti > :: value muss true für alle i sein, andernfalls ist das Verhalten undefiniert (bis C++20) ist das Programm fehlerhaft (seit C++20) .
i
-te Element des Tupels mit
std::
forward
<
Ui
>
(
std
::
get
<
i
>
(
other
)
)
.
- Dieser Konstruktor ist constexpr , wenn jede durchgeführte Operation constexpr ist. Für das leere Tupel std:: tuple <> ist es constexpr .
- std:: is_move_constructible < Ti > :: value muss für alle i true sein, andernfalls ist das Verhalten undefiniert (bis C++20) nimmt diese Überladung nicht an der Überladungsauflösung teil (seit C++20) .
Inhaltsverzeichnis |
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>
)
|