# 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

Run this code

    #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

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

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=cpp/utility/tuple/tuple&oldid=88370"