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

### 2212. `tuple_size` for `const pair` request `<tuple>` header

Section: 20.2 [utility] Status: C++17 Submitter: Alisdair Meredith Opened: 2012-11-09 Last modified: 2017-07-30

Priority: 3

View all other issues in [utility].

View all issues with C++17 status.

Discussion:

The `<utility>` header declares sufficient of the tuple API to specialize the necessary templates for `pair`, notably `tuple_size` and `tuple_element`. However, it does not make available the partial specializations that support cv-qualified template arguments, so while I can write the following after including only `<utility>`:

>     #include <utility>

>     using TestType = std::pair<int, int>;
>     static_assert(2 == std::tuple_size<TestType>(), "Pairs have two elements");
>     std::tuple_element<0, TestType>::type var{1};

the following may fail to compile unless I also include `<tuple>`:

>     #include <utility>

>     using TestType = const std::pair<int, int>;
>     static_assert(2 == std::tuple_size<TestType>(), "Pairs have two elements");
>     std::tuple_element<0, TestType>::type var{1};

Note, however, that the latter may compile with some standard library implementations but not others, leading to subtle portability issues.

[2013-03-15 Issues Teleconference]

Moved to Open.

Howard notes that we have the same issue with array, so any resolution should apply to that header too.

[2013-10-18 Daniel provides wording]

The suggested wording uses a similar approach as we already have in 23.7 [iterator.range] to ensure that the range access templates are available when at least one of an enumerated list of header files is included.

I also think that the restricted focus on `tuple_size` of this issue is too narrow and should be extended to the similar partial template specializations of `tuple_element` as well. Therefore the suggested wording ensures this as well.

[2014-03-27 Library reflector vote]

The issue has been identified as Tentatively Ready based on eight votes in favour.

Proposed resolution:

This wording is relative to N3936.

1. Change 20.5.6 [tuple.helper] as indicated:

   >     template <class T> class tuple_size<const T>;
   >     template <class T> class tuple_size<volatile T>;
   >     template <class T> class tuple_size<const volatile T>;

   > > -3- Let `TS` denote `tuple_size<T>` of the cv-unqualified type `T`. Then each of the three templates shall meet the `UnaryTypeTrait` requirements (20.10.1) with a `BaseCharacteristic` of

   > > >     integral_constant<size_t, TS::value>

   > > -?- In addition to being available via inclusion of the `<tuple>` header, each of the three templates are available when any of the headers `<array>` or `<utility>` are included.

   >     template <size_t I, class T> class tuple_element<I, const T>;
   >     template <size_t I, class T> class tuple_element<I, volatile T>;
   >     template <size_t I, class T> class tuple_element<I, const volatile T>;

   > > -?- Let `TE` denote `tuple_element<I, T>` of the cv-unqualified type `T`. Then each of the three templates shall meet the `TransformationTrait` requirements (20.10.1) with a member typedef `type` that names the following type:

   > > - for the first specialization, `add_const<TE::type>::type`,

   > > - for the second specialization, `add_volatile<TE::type>::type`, and

   > > - for the third specialization, `add_cv<TE::type>::type`.

   > > -?- In addition to being available via inclusion of the `<tuple>` header, each of the three templates are available when any of the headers `<array>` or `<utility>` are included.