tuple_size should always derive from integral_constant<size_t, N>Section: 22.4.7 [tuple.helper] Status: C++14 Submitter: Stephan T. Lavavej Opened: 2013-09-21 Last modified: 2017-07-05
Priority: 2
View all other issues in [tuple.helper].
View all issues with C++14 status.
Discussion:
In 22.4.7 [tuple.helper], the "primary template" is depicted as:
template <class... Types>
class tuple_size<tuple<Types...> >
: public integral_constant<size_t, sizeof...(Types)> { };
However, 22.3.4 [pair.astuple]/1-2 and 23.3.3.7 [array.tuple]/1-2 are underspecified, saying:
tuple_size<pair<T1, T2> >::valueReturns: Integral constant expression.
Value:2.
tuple_size<array<T, N> >::valueReturn 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.
tuple_size<cv T> to derive from
integral_constant<remove_cv<decltype(TS::value)>::type, TS::value>. This is unnecessarily overgeneralized.
tuple_size is primarily for tuples, where it is required to be size_t, and it has been extended to handle
pairs and arrays, which (as explained above) should also be guaranteed to be size_t. tuple_size<cv T>
works with cv-qualified tuples, pairs, arrays, and user-defined types that also want to participate in the tuple_size
system. It would be far simpler and perfectly reasonable to expect that user-defined types supporting the "tuple-like protocol"
should have tuple_sizes of size_t.
[Issaquah 2014-02-11: Move to Immediate]
Proposed resolution:
This wording is relative to N3691.
Edit 22.3.4 [pair.astuple]/1-2 as indicated:
tuple_size<pair<T1, T2> >::valuetemplate <class T1, class T2> struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
-1- Returns: Integral constant expression.-2- Value:2.
Edit 23.3.3.7 [array.tuple]/1-2 as indicated:
tuple_size<array<T, N> >::valuetemplate <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 22.4.7 [tuple.helper]/p1-p3 as indicated:
template <class T> struct tuple_size;-?- Remarks: All specializations of
tuple_size<T>shall meet theUnaryTypeTraitrequirements (21.3.2 [meta.rqmts]) with aBaseCharacteristicofintegral_constant<size_t, N>for someN.
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 ifIis 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 typeT. Then each of the three templates shall meet theUnaryTypeTraitrequirements (21.3.2 [meta.rqmts]) with aBaseCharacteristicofintegral_constant<remove_cv<decltype(TS::value)>::typesize_t, TS::value>