std::tuple::tuple

From cppreference.com
< cpp‎ | utility‎ | tuple
Defined in header <tuple>
(1)
constexpr tuple();
(since C++11)
(until C++17)
/*EXPLICIT*/ constexpr tuple();
(since C++17)
(2)
explicit tuple( const Types&... args );
(since C++11)
(until C++14)
explicit constexpr tuple( const Types&... args );
(since C++14)
(until C++17)
/*EXPLICIT*/ constexpr tuple( const Types&... args );
(since C++17)
(3)
template< class... UTypes >
explicit tuple( UTypes&&... args );
(since C++11)
(until C++14)
template< class... UTypes >
explicit constexpr tuple( UTypes&&... args );
(since C++14)
(until C++17)
template< class... UTypes >
/*EXPLICIT*/ constexpr tuple( UTypes&&... args );
(since C++17)
(4)
template< class... UTypes >
tuple( const tuple<UTypes...>& other );
(since C++11)
(until C++14)
template< class... UTypes >
constexpr tuple( const tuple<UTypes...>& other );
(since C++14)
(until C++17)
template< class... UTypes >
/*EXPLICIT*/ constexpr tuple( const tuple<UTypes...>& other );
(since C++17)
(5)
template <class... UTypes>
tuple( tuple<UTypes...>&& other );
(since C++11)
(until C++14)
template <class... UTypes>
constexpr tuple( tuple<UTypes...>&& other );
(since C++14)
(until C++17)
template <class... UTypes>
/*EXPLICIT*/ constexpr tuple( tuple<UTypes...>&& other );
(since C++17)
(6)
template< class U1, class U2 >
tuple( const pair<U1,U2>& p );
(since C++11)
(until C++14)
template< class U1, class U2 >
constexpr tuple( const pair<U1,U2>& p );
(since C++14)
(until C++17)
template< class U1, class U2 >
/*EXPLICIT*/ constexpr tuple( const pair<U1,U2>& p );
(since C++17)
(7)
template< class U1, class U2 >
tuple( pair<U1,U2>&& p );
(since C++11)
(until C++14)
template< class U1, class U2 >
constexpr tuple( pair<U1,U2>&& p );
(since C++14)
(until C++17)
template< class U1, class U2 >
/*EXPLICIT*/ constexpr tuple( pair<U1,U2>&& p );
(since C++17)
tuple( const tuple& other ) = default;
(8) (since C++11)
tuple( tuple&& other ) = default;
(9) (since C++11)
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a );
(10) (since C++11)
(11)
template< class Alloc >

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

       const Types&... args );
(since C++11)
(until C++17)
template< class Alloc >

/*EXPLICIT*/ tuple( std::allocator_arg_t, const Alloc& a,

                    const Types&... args );
(since C++17)
(12)
template< class Alloc, class... UTypes >

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

       UTypes&&... args );
(since C++11)
(until C++17)
template< class Alloc, class... UTypes >

/*EXPLICIT*/ tuple( std::allocator_arg_t, const Alloc& a,

                    UTypes&&... args );
(since C++17)
(13)
template <class Alloc, class... UTypes>

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

       const tuple<UTypes...>& other );
(since C++11)
(until C++17)
template <class Alloc, class... UTypes>

/*EXPLICIT*/ tuple( std::allocator_arg_t, const Alloc& a,

                    const tuple<UTypes...>& other );
(since C++17)
(14)
template< class Alloc, class... UTypes >

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

       tuple<UTypes...>&& other );
(since C++11)
(until C++17)
template< class Alloc, class... UTypes >

/*EXPLICIT*/ tuple( std::allocator_arg_t, const Alloc& a,

                    tuple<UTypes...>&& other );
(since C++17)
(15)
template< class Alloc, class U1, class U2 >

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

       const pair<U1, U2>& p );
(since C++11)
(until C++17)
template< class Alloc, class U1, class U2 >

/*EXPLICIT*/ tuple( std::allocator_arg_t, const Alloc& a,

                    const pair<U1, U2>& p );
(since C++17)
(16)
template< class Alloc, class U1, class U2 >

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

       pair<U1, U2>&& p );
(since C++11)
(until C++17)
template< class Alloc, class U1, class U2 >

/*EXPLICIT*/ tuple( std::allocator_arg_t, const Alloc& a,

                    pair<U1, U2>&& p );
(since C++17)
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a, const tuple& other );
(17) (since C++11)
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a, tuple&& other );
(18) (since C++11)

Constructs a new tuple.

1) Default constructor. Value-initializes all elements.
Requires that std::is_default_constructible<Ti>::value is true for all i
(until C++17)
This overload only participates in overload resolution if std::is_default_constructible<Ti>::value is true for all i
The constructor is explicit if and only if Ti is not implicitly default-constructible for at least one i.
(since C++17)
2) Direct constructor. Initializes each element of the tuple with the corresponding parameter.
This overload only participates in overload resolution if sizeof...(Types) >= 1 and std::is_copy_constructible<Ti>::value is true for all i.
This constructor is explicit if and only if std::is_convertible<const Ti&, Ti>::value is false for at least one i.
(since C++17)
3) Converting constructor. Initializes each element of the tuple with the corresponding value in std::forward<Utypes>(args).
Requires that sizeof...(Types) == sizeof...(UTypes)
This overload only participates in overload resolution if sizeof...(Types) >= 1 and std::is_constructible<Ti, Ui&&>::value is true for all i.
(until C++17)
This overload only participates in overload resolution if sizeof...(Types) == sizeof...(UTypes) and sizeof...(Types) >= 1 and std::is_constructible<Ti, Ui&&>::value is true for all i.
The constructor is explicit if and only if std::is_convertible<Ui&&, Ti>::value is false for at least one i.
(since C++17)
4) Converting copy-constructor. For all i in sizeof...(UTypes), initializes ith element of the tuple with std::get<i>(other).
Requires that sizeof...(Types) == sizeof...(UTypes)
This overload only participates in overload resolution if std::is_constructible<Ti, const Ui&>::value is true for all i.
(until C++17)
This overload only participates in overload resolution if

sizeof...(Types) == sizeof...(UTypes) and
std::is_constructible_v<Ti, const Ui&> is true for all i and
sizeof...(Types) != 1 or

(when Types... expands to T and UTypes... expands to U) std::is_convertible_v<const tuple<U>&, T>, std::is_constructible_v<T, const tuple<U>&>, and std::is_same_v<T, U> are all false .
The constructor is explicit if and only if std::is_convertible<const Ui&, Ti>::value is false for at least one i.
(since C++17)
5) Converting move-constructor. For all i in sizeof...(UTypes), initializes ith element of the tuple with std::forward<Ui>(std::get<i>(other)).
Requires that sizeof...(Types) == sizeof...(UTypes)
This overload only participates in overload resolution if std::is_constructible<Ti, Ui&&>::value is true for all i.
(until C++17)
This overload only participates in overload resolution if

sizeof...(Types) == sizeof...(UTypes) and
std::is_constructible_v<Ti, Ui&&> is true for all i and
sizeof...(Types) != 1 or

(when Types... expands to T and UTypes... expands to U) std::is_convertible_v<tuple<U>, T>, std::is_constructible_v<T, tuple<U>>, and std::is_same_v<T, U> are all false .
The constructor is explicit if and only if std::is_convertible<Ui&&, Ti>::value is false for at least one i.
(since C++17)
6) Pair copy constructor. Constructs a 2-element tuple with the first element constructed from p.first and the second element from p.second
Requires that sizeof...(Types) == 2
This overload only participates in overload resolution if std::is_constructible<T0,const U1&>::value and std::is_constructible<T1, const U2&>::value are both true
(until C++17)
This overload only participates in overload resolution if sizeof...(Types) == 2 and std::is_constructible<T0,const U1&>::value and std::is_constructible<T1, const U2&>::value are both true
The constructor is explicit if and only if std::is_convertible<const U1&, T0>::value or std::is_convertible<const U2&, T1>::value is false
(since C++17)
7) Pair move constructor. Constructs a 2-element tuple with the first element constructed from std::forward<U1>(p.first) and the second element from std::forward<U2>(p.second)
Requires that sizeof...(Types) == 2
This overload only participates in overload resolution if std::is_constructible<T0, U1&&>::value and std::is_constructible<T1, U2&&>::value are both true
(until C++17)
This overload only participates in overload resolution if sizeof...(Types) == 2 and std::is_constructible<T0, U1&&>::value and std::is_constructible<T1, U2&&>::value are both true
The constructor is explicit if and only if std::is_convertible<U1&&, T0>::value or std::convertible<U2&&, T1>::value is false
(since C++17)
8) Implicitly-defined copy constructor. Initializes each element of the tuple with the corresponding element of other.
This constructor is constexpr if every operation it performs is constexpr. For the empty tuple std::tuple<>, it is constexpr.
Requires that std::is_copy_constructible<Ti>::value is true for all i.
9) Implicitly-defined move constructor. Initializes each ith element of the tuple with std::forward<Ui>(std::get<i>(other)).
This constructor is constexpr if every operation it performs is constexpr. For the empty tuple std::tuple<>, it is constexpr.
Requires that std::is_move_constructible<Ti>::value is true for all i.
10-18) Identical to (1-9) except each element is created by uses-allocator construction, that is, the Allocator object a is passed as an additional argument to the constructor of each element for which std::uses_allocator<Ui, Alloc>::value is true.

Parameters

args - values used to initialize each element of the tuple
other - a tuple of values used to initialize each element of the tupe
p - pair of values used to initialize both elements of this 2-tuple
a - allocator to use in uses-allocator construction

Notes

Conditionally-explicit constructors in C++17 make it possible to construct a tuple in copy-initialization context using list-initialization syntax:

std::tuple<int, int> foo_tuple() 
{
  return {1, -1};  // Error until C++17
  return std::make_tuple(1, -1); // Always works
}

Note that if some element of the list is not implicitly convertible to the corresponding element of the target tuple, the constructors become explicit

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}); // Error: int is not implicitly convertible to duration
launch_rocket_at(std::tuple<hours, minutes, seconds>{1, 2, 3}); // OK

Example

#include <iostream>
#include <string>
#include <vector>
#include <tuple>
#include <memory>
 
// helper function to print a tuple of any size
template<class Tuple, std::size_t N>
struct TuplePrinter {
    static void print(const Tuple& t) 
    {
        TuplePrinter<Tuple, N-1>::print(t);
        std::cout << ", " << std::get<N-1>(t);
    }
};
 
template<class Tuple>
struct TuplePrinter<Tuple, 1>{
    static void print(const Tuple& t) 
    {
        std::cout << std::get<0>(t);
    }
};
 
template<class... Args>
void print(const std::tuple<Args...>& t) 
{
    std::cout << "(";
    TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
    std::cout << ")\n";
}
// end helper function
 
int main()
{
    std::tuple<int, std::string, double> t1;
    std::cout << "Value-initialized: "; print(t1);
    std::tuple<int, std::string, double> t2(42, "Test", -3.14);
    std::cout << "Initialized with values: "; print(t2);
    std::tuple<char, std::string, int> t3(t2);
    std::cout << "Implicitly converted: "; print(t3);
    std::tuple<int, double> t4(std::make_pair(42, 3.14));
    std::cout << "Constructed from a pair"; print(t4);
 
    // given Allocator my_alloc with a single-argument constructor my_alloc(int)
    // use my_alloc(1) to allocate 10 ints in a vector
    std::vector<int, my_alloc> v(10, 1, my_alloc(1));
    // use my_alloc(2) to allocate 10 ints in a vector in a tuple
    std::tuple<int, std::vector<int, my_alloc>, double> t5(std::allocator_arg,
                                                           my_alloc(2), 42, v,  -3.14);
}

Output:

Value-initialized: (0, , 0)
Initialized with values: (42, Test, -3.14)
Implicitly converted: (*, Test, -3)
Constructed from a pair(42, 3.14)

See also

creates a tuple object of the type defined by the argument types
(function template)
creates a tuple of lvalue references or unpacks a tuple into individual objects
(function template)
creates a tuple of rvalue references
(function template)