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.

1385. 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 tuples. A single variadic signature that can concatenate an arbitrary number of tuples 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 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<see below> implies it, the specification of the contained tuple element types is missing. Second, the term "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.

  1. 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&&...);
    
    ...
    
    
  2. 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 ith type in Tuples, Ui be remove_reference<Ti>::type, and tpi be the ith 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 cvi tuple<Argsi...>, where cvi is the (possibly empty) ith cv-qualifier-seq, and Argsi is the parameter pack representing the element types in Ui. Let Aik be the kith type in Argsi, then for all Aik the following requirements shall be satisfied: If Ti is deduced as an lvalue reference type, then is_constructible<Aik, cvi Aik&>::value == true, otherwise is_constructible<Aik, cvi Aik&&>::value == true.

    10 Remarks: The types in CTypes shall be equal to the ordered sequence of the expanded types Args0..., Args1..., Argsn-1..., where n equals sizeof...(Tuples). Let ei... be the ith ordered sequence of tuple elements of the result tuple object corresponding to the type sequence Argsi.

    11 Returns: A tuple object constructed by initializing the kith type element eik in ei... with get<ki>(std::forward<Ti>(tpi)) for each valid ki and each element group ei in order.

    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]