**Section:** 23.5.3.6 [tuple.helper] **Status:** C++14
**Submitter:** Stephan T. Lavavej **Opened:** 2013-09-21 **Last modified:** 2017-07-06

**Priority: **2

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

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

**Discussion:**

In 23.5.3.6 [tuple.helper], the "primary template" is depicted as:

template <class... Types> class tuple_size<tuple<Types...> > : public integral_constant<size_t, sizeof...(Types)> { };

However, 23.4.4 [pair.astuple]/1-2 and 26.3.7.6 [array.tuple]/1-2 are underspecified, saying:

tuple_size<pair<T1, T2> >::value

Returns:Integral constant expression.

Value:2.

tuple_size<array<T, N> >::value

Return type:integral constant expression.

Value:N

They should be required to behave like the "primary template". This is more than a stylistic decision — it allows
`tuple_size` to be passed to a function taking `integral_constant`.

LWG 1118 noticed this underspecification, but instead of correcting it, the resolution changed
23.5.3.6 [tuple.helper]/3 to require `tuple_size< cv T>` to derive from

*[Issaquah 2014-02-11: Move to Immediate]*

**Proposed resolution:**

This wording is relative to N3691.

Edit 23.4.4 [pair.astuple]/1-2 as indicated:

~~tuple_size<pair<T1, T2> >::value~~template <class T1, class T2> struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };~~-1-~~*Returns:*Integral constant expression.~~-2-~~*Value:*`2`.Edit 26.3.7.6 [array.tuple]/1-2 as indicated:

~~tuple_size<array<T, N> >::value~~template <class T, size_t N> struct tuple_size<array<T, N>> : integral_constant<size_t, N> { };~~-1-~~*Returns:*Integral constant expression.~~-2-~~*Value:*`N`.Edit 23.5.3.6 [tuple.helper]/p1-p3 as indicated:

template <class T> struct tuple_size;

-?-

*Remarks:*All specializations of`tuple_size<T>`shall meet the`UnaryTypeTrait`requirements (23.15.1 [meta.rqmts]) with a`BaseCharacteristic`of`integral_constant<size_t, N>`for some`N`.template <class... Types> struct tuple_size<tuple<Types...> > : integral_constant<size_t, sizeof...(Types)> { }; template <size_t I, class... Types> class tuple_element<I, tuple<Types...> > { public: typedef TI type; };

-1-

*Requires:*`I < sizeof...(Types)`. The program is ill-formed if`I`is out of bounds.[…]

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 (23.15.1 [meta.rqmts]) with a`BaseCharacteristic`ofintegral_constant<

~~remove_cv<decltype(TS::value)>::type~~size_t, TS::value>