*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.*

`tuple_cat`

should be a single variadic signature**Section:** 22.4.5 [tuple.creation] **Status:** C++11
**Submitter:** BSI **Opened:** 2010-08-25 **Last modified:** 2016-01-28

**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

`tuple`

s and neither requiring nor outlawing support for other`tuple`

-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<`

implies it, the specification of the contained tuple element types is missing. Second, the term "*see below*>`tuple`

protocol" is not defined anywhere and I see no reason why this normative wording should not be a non-normative
note. We could at least give a better approximation, maybe "tuple-like protocol" as indicated from header
`<utility>`

synopsis. Further, it seems to me that the effects need to contain a combination of `std::forward`

with the call of `get`

. Finally I suggest to replace the requirements `Move/CopyConstructible`

by proper usage of `is_constructible`

, as indicated by n3140.

*[
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 22.4.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 22.4.5 [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 in

shall be equal to the ordered sequence of the expanded types*CTypes*`Args`

, where_{0}..., Args_{1}..., Args_{n-1}...

equals*n*`sizeof...(Tuples)`

. Let

be 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`

in

with*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*]