*This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.*

**Section:** 20.5.4 [tuple.creation] **Status:** C++11
**Submitter:** BSI **Opened:** 2010-08-25 **Last modified:** 2016-02-10

**Priority: **Not Prioritized

**View all other** issues in [tuple.creation].

**View all issues with** C++11 status.

**Discussion:**

**Addresses GB-88**

The `tuple_cat` template consists of four overloads and that
can concatenate only two `tuple`s. A single variadic
signature that can concatenate an arbitrary number of
`tuple`s would be preferred.

*[
Resolution proposed by ballot comment:
]*

Adopt a simplified form of the proposal in n2975, restricted to

tuples and neither requiring nor outlawing support for othertuple-like types.

*[
2010 Rapperswil: Alisdair to provide wording.
]*

*[
2010-11-06: Daniel comments and proposes some alternative wording:
]*

There are some problems in the wording: First, even though the result type `tuple< see below>`
implies it, the specification of the contained tuple element types is missing. Second, the term "

*[
2010 Batavia
]*

Moved to Ready with Daniel's improved wording.

**Proposed resolution:**

Note: This alternate proposed resolution works only if 1191 has been accepted.

- Change 20.5.1 [tuple.general] p. 2, header
`<tuple>`synopsis, as indicated:namespace std { ... //

*20.4.2.4, tuple creation functions:*const unspecified ignore; template <class... Types> tuple<*VTypes*...> make_tuple(Types&&...); template <class... Types> tuple<*ATypes*...> forward_as_tuple(Types&&...); template<class... Types> tuple<Types&...> tie(Types&...);~~template <class... TTypes, class... UTypes> tuple<TTypes..., UTypes...> tuple_cat(const tuple<TTypes...>&, const tuple<UTypes...>&); template <class... TTypes, class... UTypes> tuple<TTypes..., UTypes...> tuple_cat(tuple<TTypes...>&&, const tuple<UTypes...>&); template <class... TTypes, class... UTypes> tuple<TTypes..., UTypes...> tuple_cat(const tuple<TTypes...>&, tuple<UTypes...>&&); template <class... TTypes, class... UTypes> tuple<TTypes..., UTypes...> tuple_cat(tuple<TTypes...>&&, tuple<UTypes...>&&);~~template <class... Tuples> tuple<*CTypes*...> tuple_cat(Tuples&&...); ... - Change 20.5.4 [tuple.creation] as indicated:
~~template <class... TTypes, class... UTypes> tuple<TTypes..., UTypes...> tuple_cat(const tuple<TTypes...>& t, const tuple<UTypes...>& u);~~~~8~~*Requires*: All the types in`TTypes`shall be`CopyConstructible`(Table 35). All the types in`UTypes`shall be`CopyConstructible`(Table 35).~~9~~*Returns*: A`tuple`object constructed by copy constructing its first`sizeof...(TTypes)`elements from the corresponding elements of`t`and copy constructing its last`sizeof...(UTypes)`elements from the corresponding elements of`u`.~~template <class... TTypes, class... UTypes> tuple<TTypes..., UTypes...> tuple_cat(tuple<TTypes...>&& t, const tuple<UTypes...>& u);~~~~10~~*Requires*: All the types in`TTypes`shall be`MoveConstructible`(Table 34). All the types in`UTypes`shall be`CopyConstructible`(Table 35).~~11~~*Returns*: A`tuple`object constructed by move constructing its first`sizeof...(TTypes)`elements from the corresponding elements of`t`and copy constructing its last`sizeof...(UTypes)`elements from the corresponding elements of`u`.~~template <class... TTypes, class... UTypes> tuple<TTypes..., UTypes...> tuple_cat(const tuple<TTypes...>& t, tuple<UTypes...>&& u);~~~~12~~*Requires*: All the types in`TTypes`shall be`CopyConstructible`(Table 35). All the types in`UTypes`shall be`MoveConstructible`(Table 34).~~13~~*Returns*: A`tuple`object constructed by copy constructing its first`sizeof...(TTypes)`elements from the corresponding elements of`t`and move constructing its last`sizeof...(UTypes)`elements from the corresponding elements of`u`.~~template <class... TTypes, class... UTypes> tuple<TTypes..., UTypes...> tuple_cat(tuple<TTypes...>&& t, tuple<UTypes...>&& u);~~~~14~~*Requires*: All the types in`TTypes`shall be`MoveConstructible`(Table 34). All the types in`UTypes`shall be`MoveConstructible`(Table 34).~~15~~*Returns*: A`tuple`object constructed by move constructing its first`sizeof...(TTypes)`elements from the corresponding elements of`t`and move constructing its last`sizeof...(UTypes)`elements from the corresponding elements of`u`.template <class... Tuples> tuple<

*CTypes*...> tuple_cat(Tuples&&... tpls);8 Let

`Ti`be the*i*^{th}type in`Tuples`,`Ui`be`remove_reference<Ti>::type`, and`tp`be the_{i}*i*^{th}parameter in the function parameter pack`tpls`, where all indexing is zero-based in the following paragraphs of this sub-clause [tuple.creation].9

*Requires*: For all,*i*`Ui`shall be the type*cv*_{i}`tuple<Args`, where_{i}...>*cv*is the (possibly empty)_{i}*i*^{th}*cv*-qualifier-seq, and`Args`is the parameter pack representing the element types in_{i}`Ui`. Let`Aik`be the*k*_{i}^{th}type in`Args`, then for all_{i}`Aik`the following requirements shall be satisfied: If`Ti`is deduced as an lvalue reference type, then`is_constructible<Aik,`, otherwise*cv*Aik&>::value == true_{i}`is_constructible<Aik,`.*cv*Aik&&>::value == true_{i}10

*Remarks*: The types inshall be equal to the ordered sequence of the expanded types*CTypes*`Args`, where_{0}..., Args_{1}..., Args_{n-1}...equals*n*`sizeof...(Tuples)`. Letbe the*e*..._{i}*i*^{th}ordered sequence of tuple elements of the result`tuple`object corresponding to the type sequence`Args`._{i}11

*Returns*: A`tuple`object constructed by initializing the*k*_{i}^{th}type element`eik`inwith*e*..._{i}`get<`for each valid*k*>(std::forward<Ti>(tp_{i}_{i}))and each element group*k*_{i}in order.*e*_{i}12 [

*Note*: An implementation may support additional types in the parameter pack`Tuples`, such as`pair`and`array`that support the`tuple`-like protocol. —*end note*]