std::tuple<Types...>:: tuple
|
Определено в заголовочном файле
<tuple>
|
||
|
constexpr
tuple
(
)
;
|
(1) |
(начиная с C++11)
(условно явный) |
|
tuple
(
const
Types
&
...
args
)
;
|
(2) |
(начиная с C++11)
(constexpr начиная с C++14) (условно explicit) |
|
template
<
class
...
UTypes
>
tuple ( UTypes && ... args ) ; |
(3) |
(начиная с C++11)
(constexpr начиная с C++14) (условно explicit) |
|
template
<
class
...
UTypes
>
constexpr tuple ( tuple < UTypes... > & other ) ; |
(4) |
(начиная с C++23)
(условно explicit) |
|
template
<
class
...
UTypes
>
tuple ( const tuple < UTypes... > & other ) ; |
(5) |
(начиная с C++11)
(constexpr начиная с C++14) (условно explicit) |
|
template
<
class
...
UTypes
>
tuple ( tuple < UTypes... > && other ) ; |
(6) |
(начиная с C++11)
(constexpr начиная с C++14) (условно explicit) |
|
template
<
class
...
UTypes
>
constexpr tuple ( const tuple < UTypes... > && other ) ; |
(7) |
(начиная с C++23)
(условно explicit) |
|
template
<
class
U1,
class
U2
>
constexpr tuple ( std:: pair < U1, U2 > & p ) ; |
(8) |
(начиная с C++23)
(условно explicit) |
|
template
<
class
U1,
class
U2
>
tuple ( const std:: pair < U1, U2 > & p ) ; |
(9) |
(начиная с C++11)
(constexpr начиная с C++14) (условно explicit) |
|
template
<
class
U1,
class
U2
>
tuple ( std:: pair < U1, U2 > && p ) ; |
(10) |
(начиная с C++11)
(constexpr начиная с C++14) (условно explicit) |
|
template
<
class
U1,
class
U2
>
constexpr tuple ( const std:: pair < U1, U2 > && p ) ; |
(11) |
(начиная с C++23)
(условно explicit) |
|
template
<
tuple
-
like UTuple
>
constexpr tuple ( UTuple && u ) ; |
(12) |
(начиная с C++23)
(условно explicit) |
|
tuple
(
const
tuple
&
other
)
=
default
;
|
(13) | (начиная с C++11) |
|
tuple
(
tuple
&&
other
)
=
default
;
|
(14) | (начиная с C++11) |
|
Конструкторы с расширенным аллокатором
|
||
|
template
<
class
Alloc
>
tuple ( std:: allocator_arg_t , const Alloc & a ) ; |
(15) |
(начиная с C++11)
(constexpr начиная с C++20) (условно explicit) |
|
template
<
class
Alloc
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(16) |
(начиная с C++11)
(constexpr начиная с C++20) (условно explicit) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(17) |
(начиная с C++11)
(constexpr начиная с C++20) (условно explicit) |
|
template
<
class
Alloc,
class
...
UTypes
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(18) |
(начиная с C++23)
(условно explicit) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(19) |
(начиная с C++11)
(constexpr начиная с C++20) (условно explicit) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(20) |
(начиная с C++11)
(constexpr начиная с C++20) (условно explicit) |
|
template
<
class
Alloc,
class
...
UTypes
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(21) |
(начиная с C++23)
(условно explicit) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(22) |
(начиная с C++23)
(условно explicit) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(23) |
(начиная с C++11)
(constexpr начиная с C++20) (условно explicit) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(24) |
(начиная с C++11)
(constexpr начиная с C++20) (условно explicit) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(25) |
(начиная с C++23)
(условно explicit) |
|
template
<
class
Alloc, tuple
-
like UTuple
>
constexpr tuple ( std:: allocator_arg_t , const Alloc & a, UTuple && u ) ; |
(26) |
(начиная с C++23)
(условно explicit) |
|
template
<
class
Alloc
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(27) |
(начиная с C++11)
(constexpr начиная с C++20) |
|
template
<
class
Alloc
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(28) |
(начиная с C++11)
(constexpr начиная с C++20) |
Создает новый кортеж.
В следующих описаниях пусть
-
i
находится в диапазоне
[ 0 ,sizeof... ( Types ))по порядку, -
Tiявляетсяi-м типом вTypes, и -
Uiявляетсяi-м типом в пакете параметров шаблона с именемUTypes,
где индексация начинается с нуля.
- Эта перегрузка участвует в разрешении перегрузки только если std:: is_default_constructible < Ti > :: value равно true для всех i .
-
Конструктор является
explicit
тогда и только тогда, когда
Tiне может быть copy-list-инициализирован из { } хотя бы для одного i .
- Эта перегрузка участвует в разрешении перегрузки только если sizeof... ( Types ) >= 1 и std:: is_copy_constructible < Ti > :: value равно true для всех i .
- Этот конструктор является explicit тогда и только тогда, когда std:: is_convertible < const Ti & , Ti > :: value равно false хотя бы для одного i .
-
Эта перегрузка участвует в разрешении перегрузки только если
- sizeof... ( Types ) == sizeof... ( UTypes ) ,
- sizeof... ( Types ) >= 1 ,
- std:: is_constructible < Ti, Ui > :: value равно true для всех i , и
-
пусть
Dбудет std:: decay < U0 > :: type (до C++20) std:: remove_cvref_t < U0 > (начиная с C++20) ,-
если
sizeof...
(
Types
)
==
1
, то
Dне являетсяstd::tuple, иначе, -
если
sizeof...
(
Types
)
==
2
или
sizeof...
(
Types
)
==
3
, то либо
Dне является std::allocator_arg_t , либоT0является std::allocator_arg_t .
-
если
sizeof...
(
Types
)
==
1
, то
- Конструктор является explicit тогда и только тогда, когда std:: is_convertible < Ui, Ti > :: value равно false хотя бы для одного i .
|
(начиная с C++23) |
Формально, пусть
FWD
(
other
)
будет
std::
forward
<
decltype
(
other
)
>
(
other
)
, тогда для всех
i
, инициализирует
i
-й элемент кортежа значением
std
::
get
<
i
>
(
FWD
(
other
)
)
.
-
Эта перегрузка участвует в разрешении перегрузки только если
- sizeof... ( Types ) == sizeof... ( UTypes ) ,
- std:: is_constructible_v < Ti, decltype ( std :: get < i > ( FWD ( other ) ) ) > равно true для всех i , и
-
либо
- sizeof... ( Types ) не равно 1 , либо
-
(когда
Types...раскрывается вTиUTypes...раскрывается вU) std:: is_convertible_v < decltype ( other ) , T > , std:: is_constructible_v < T, decltype ( other ) > , и std:: is_same_v < T, U > все равны false .
- Эти конструкторы являются explicit тогда и только тогда, когда std:: is_convertible_v < decltype ( std :: get < i > ( FWD ( other ) ) ) , Ti > равно false хотя бы для одного i .
|
(начиная с C++23) |
Формально, пусть FWD ( p ) будет std:: forward < decltype ( p ) > ( p ) , инициализирует первый элемент с помощью std :: get < 0 > ( FWD ( p ) ) и второй элемент с помощью std :: get < 1 > ( FWD ( p ) ) .
-
Эта перегрузка участвует в разрешении перегрузки только если
- sizeof... ( Types ) == 2 ,
- std:: is_constructible_v < T0, decltype ( std :: get < 0 > ( FWD ( p ) ) ) > равно true , и
- std:: is_constructible_v < T1, decltype ( std :: get < 1 > ( FWD ( p ) ) ) > равно true .
- Конструктор является explicit тогда и только тогда, когда std:: is_convertible_v < decltype ( std :: get < 0 > ( FWD ( p ) ) ) , T0 > или std:: is_convertible_v < decltype ( std :: get < 1 > ( FWD ( p ) ) ) , T1 > равно false .
|
(since C++23) |
tuple-like
конструктор. Создает кортеж, где каждый элемент конструируется из соответствующего элемента
u
.
Формально, для всех
i
, инициализирует
i
-й элемент кортежа с помощью
std
::
get
<
i
>
(
std::
forward
<
UTuple
>
(
u
)
)
.
-
Эта перегрузка участвует в разрешении перегрузки только если
- std:: same_as < std:: remove_cvref_t < UTuple > , std:: tuple > равно false ,
- std:: remove_cvref_t < UTuple > не является специализацией std::ranges::subrange ,
- sizeof... ( Types ) равно std:: tuple_size_v < std:: remove_cvref_t < UTuple >> ,
- std:: is_constructible_v < Ti, decltype ( std :: get < i > ( std:: forward < UTuple > ( u ) ) ) > равно true для всех i , и
-
либо
- sizeof... ( Types ) не равно 1 , либо
-
(когда
Types...раскрывается вT) std:: is_convertible_v < UTuple, T > и std:: is_constructible_v < T, UTuple > оба равны false .
- Этот конструктор определяется как удаленный, если инициализация любого элемента, являющегося ссылкой, привела бы к его привязке к временному объекту.
- Этот конструктор является constexpr , если каждая выполняемая им операция является constexpr . Для пустого кортежа std:: tuple <> , он является constexpr .
- std:: is_copy_constructible < Ti > :: value должно быть true для всех i , иначе поведение не определено (до C++20) программа является некорректной (начиная с C++20) .
i
-й элемент кортежа с помощью
std::
forward
<
Ui
>
(
std
::
get
<
i
>
(
other
)
)
.
- Этот конструктор является constexpr , если каждая выполняемая им операция является constexpr . Для пустого кортежа std:: tuple <> , он является constexpr .
- std:: is_move_constructible < Ti > :: value должно быть true для всех i , иначе поведение не определено (до C++20) эта перегрузка не участвует в разрешении перегрузки (начиная с C++20) .
Содержание |
Параметры
| args | - | значения, используемые для инициализации каждого элемента кортежа |
| other | - | кортеж значений, используемых для инициализации каждого элемента кортежа |
| p | - | пара значений, используемая для инициализации обоих элементов 2-кортежа |
| u | - |
tuple-like
объект значений, используемый для инициализации каждого элемента кортежа
|
| a | - | аллокатор, используемый при uses-allocator конструировании |
Примечания
Условно-явные конструкторы позволяют создавать кортеж в контексте копирующей инициализации, используя синтаксис списковой инициализации:
std::tuple<int, int> foo_tuple() { // return {1, -1}; // Ошибка до N4387 return std::make_tuple(1, -1); // Всегда работает }
Обратите внимание, что если какой-либо элемент списка не является неявно преобразуемым в соответствующий элемент целевого кортежа, конструкторы становятся явными:
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}); // Ошибка: int не преобразуется неявно в duration launch_rocket_at(std::tuple<hours, minutes, seconds>{1, 2, 3}); // OK
Пример
#include <iomanip> #include <iostream> #include <memory> #include <string> #include <string_view> #include <tuple> #include <type_traits> #include <vector> // вспомогательная функция для вывода вектора в поток 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; } // вспомогательная функция для вывода кортежа любого размера 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"; } // конец вспомогательной функции int main() { std::tuple<int, std::string, double> t1; print("Инициализированное значением, t1:", t1); std::tuple<int, std::string, double> t2{42, "Тест", -3,14}; print("Инициализировано со значениями, t2:", t2); std::tuple<char, std::string, int> t3{t2}; print("Неявно преобразовано, t3:", t3); std::tuple<int, double> t4{std::make_pair(42, 3,14)}; print("Сконструировано из пары, t4:", t4); // дан Allocator my_alloc с однопараметрическим конструктором // my_alloc(int); используйте my_alloc(1) для выделения 5 целых чисел в векторе using my_alloc = std::allocator<int>; std::vector<int, my_alloc> v{5, 1, my_alloc{/* 1 */}}; // использование my_alloc(2) для выделения 5 целых чисел в векторе внутри кортежа std::tuple<int, std::vector<int, my_alloc>, double> t5 {std::allocator_arg, my_alloc{/* 2 */}, 42, v, -3,14}; print("Сконструировано с аллокатором, t5:", t5); }
Возможный вывод:
Инициализированное значением по умолчанию, t1: (0, "", 0)
Инициализировано значениями, t2: (42, "Test", -3.14)
Неявно преобразовано, t3: ('*', "Test", -3)
Сконструировано из пары, t4: (42, 3.14)
Сконструировано с аллокатором, t5: (42, {1,1,1,1,1}, -3.14)
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| LWG 2510 | C++11 | конструктор по умолчанию был неявным | сделан условно-явным |
| LWG 3121 | C++11 |
конструктор 1-кортежа мог рекурсивно проверять ограничения;
allocator_arg_t
аргумент вызывал неоднозначность
|
дополнительно ограничен
конструктор |
| LWG 3158 | C++11 |
конструктор с использованием аллокатора, соответствующий
конструктору по умолчанию, был неявным |
сделан условно-явным |
| LWG 3211 | C++11 |
является ли конструктор по умолчанию
tuple<>
тривиальным, не было указано
|
требуется быть тривиальным |
| LWG 4045 | C++23 |
tuple-like
конструктор может потенциально создавать висячие ссылки
|
определен как удаленный |
| N4387 | C++11 | некоторые конструкторы были явными, что препятствовало полезному поведению |
большинство конструкторов сделано
условно-явными |
Смотрите также
присваивает содержимое одного
tuple
другому
(public member function) |
|
|
(C++11)
|
создаёт объект
tuple
типа, определённого типами аргументов
(function template) |
|
(C++11)
|
создаёт
tuple
ссылок на lvalue или распаковывает tuple в отдельные объекты
(function template) |
|
(C++11)
|
создаёт
tuple
из
forwarding references
(function template) |
создаёт новый
pair
(public member function of
std::pair<T1,T2>
)
|