Namespaces
Variants

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

From cppreference.net
Utilities library
(Примечание: В данном фрагменте HTML отсутствует текстовое содержимое для перевода - присутствуют только HTML-теги и атрибуты, которые согласно инструкциям не подлежат переводу)
Определено в заголовочном файле <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,

const Types & ... args ) ;
(16) (начиная с C++11)
(constexpr начиная с C++20)
(условно explicit)
template < class Alloc, class ... UTypes >

tuple ( std:: allocator_arg_t , const Alloc & a,

UTypes && ... args ) ;
(17) (начиная с C++11)
(constexpr начиная с C++20)
(условно explicit)
template < class Alloc, class ... UTypes >

constexpr tuple ( std:: allocator_arg_t , const Alloc & a,

tuple < UTypes... > & other ) ;
(18) (начиная с C++23)
(условно explicit)
template < class Alloc, class ... UTypes >

tuple ( std:: allocator_arg_t , const Alloc & a,

const tuple < UTypes... > & other ) ;
(19) (начиная с C++11)
(constexpr начиная с C++20)
(условно explicit)
template < class Alloc, class ... UTypes >

tuple ( std:: allocator_arg_t , const Alloc & a,

tuple < UTypes... > && other ) ;
(20) (начиная с C++11)
(constexpr начиная с C++20)
(условно explicit)
template < class Alloc, class ... UTypes >

constexpr tuple ( std:: allocator_arg_t , const Alloc & a,

const tuple < UTypes... > && other ) ;
(21) (начиная с C++23)
(условно explicit)
template < class Alloc, class U1, class U2 >

constexpr tuple ( std:: allocator_arg_t , const Alloc & a,

std:: pair < U1, U2 > & p ) ;
(22) (начиная с C++23)
(условно explicit)
template < class Alloc, class U1, class U2 >

tuple ( std:: allocator_arg_t , const Alloc & a,

const std:: pair < U1, U2 > & p ) ;
(23) (начиная с C++11)
(constexpr начиная с C++20)
(условно explicit)
template < class Alloc, class U1, class U2 >

tuple ( std:: allocator_arg_t , const Alloc & a,

std:: pair < U1, U2 > && p ) ;
(24) (начиная с C++11)
(constexpr начиная с C++20)
(условно explicit)
template < class Alloc, class U1, class U2 >

constexpr tuple ( std:: allocator_arg_t , const Alloc & a,

const std:: pair < U1, U2 > && p ) ;
(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,

const tuple & other ) ;
(27) (начиная с C++11)
(constexpr начиная с C++20)
template < class Alloc >

tuple ( std:: allocator_arg_t , const Alloc & a,

tuple && other ) ;
(28) (начиная с C++11)
(constexpr начиная с C++20)

Создает новый кортеж.

В следующих описаниях пусть

  • i находится в диапазоне [ 0 , sizeof... ( Types ) ) по порядку,
  • Ti является i -м типом в Types , и
  • Ui является i -м типом в пакете параметров шаблона с именем UTypes ,

где индексация начинается с нуля.

1) Конструктор по умолчанию. Выполняет value-инициализацию всех элементов, если они есть. Конструктор по умолчанию является тривиальным, если sizeof... ( Types ) == 0 .
  • Эта перегрузка участвует в разрешении перегрузки только если std:: is_default_constructible < Ti > :: value равно true для всех i .
  • Конструктор является explicit тогда и только тогда, когда Ti не может быть copy-list-инициализирован из { } хотя бы для одного i .
2) Прямой конструктор. Инициализирует каждый элемент кортежа соответствующим параметром.
  • Эта перегрузка участвует в разрешении перегрузки только если sizeof... ( Types ) >= 1 и std:: is_copy_constructible < Ti > :: value равно true для всех i .
  • Этот конструктор является explicit тогда и только тогда, когда std:: is_convertible < const Ti & , Ti > :: value равно false хотя бы для одного i .
3) Конвертирующий конструктор. Инициализирует каждый элемент кортежа соответствующим значением в std:: forward < UTypes > ( args ) .
  • Эта перегрузка участвует в разрешении перегрузки только если
    • 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 .
  • Конструктор является explicit тогда и только тогда, когда std:: is_convertible < Ui, Ti > :: value равно false хотя бы для одного i .
(начиная с C++23)
4-7) Конвертирующий конструктор. Инициализирует каждый элемент кортежа соответствующим элементом из other .

Формально, пусть 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 , и
    • либо
  • Эти конструкторы являются explicit тогда и только тогда, когда std:: is_convertible_v < decltype ( std :: get < i > ( FWD ( other ) ) ) , Ti > равно false хотя бы для одного i .
  • Эти конструкторы определяются как удаленные, если инициализация любого элемента, являющегося ссылкой, привела бы к привязке к временному объекту.
(начиная с C++23)
8-11) Конструктор из пары. Создает кортеж из 2 элементов, где каждый элемент конструируется из соответствующего элемента p .

Формально, пусть FWD ( p ) будет std:: forward < decltype ( p ) > ( p ) , инициализирует первый элемент с помощью std :: get < 0 > ( FWD ( p ) ) и второй элемент с помощью std :: get < 1 > ( FWD ( p ) ) .

  • Эта перегрузка участвует в разрешении перегрузки только если
  • Конструктор является 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)
12) tuple-like конструктор. Создает кортеж, где каждый элемент конструируется из соответствующего элемента u .

Формально, для всех i , инициализирует i -й элемент кортежа с помощью std :: get < i > ( std:: forward < UTuple > ( u ) ) .

13) Неявно определенный конструктор копирования. Инициализирует каждый элемент кортежа соответствующим элементом other .
  • Этот конструктор является constexpr , если каждая выполняемая им операция является constexpr . Для пустого кортежа std:: tuple <> , он является constexpr .
  • std:: is_copy_constructible < Ti > :: value должно быть true для всех i , иначе поведение не определено (до C++20) программа является некорректной (начиная с C++20) .
14) Неявно определенный конструктор перемещения. Для всех i , инициализирует 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) .
15-28) Идентично (1-14) за исключением того, что каждый элемент создаётся с помощью uses-allocator construction , то есть объект аллокатора a передаётся как дополнительный аргумент конструктору каждого элемента, для которого std:: uses_allocator < Ui, Alloc > :: value равно true .

Содержание

Параметры

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)
создаёт tuple из forwarding references
(function template)
создаёт новый pair
(public member function of std::pair<T1,T2> )