This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++14 status.
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 theUnaryTypeTrait
requirements (21.3.2 [meta.rqmts]) with aBaseCharacteristic
ofintegral_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 ifI
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 typeT
. Then each of the three templates shall meet theUnaryTypeTrait
requirements (21.3.2 [meta.rqmts]) with aBaseCharacteristic
ofintegral_constant<remove_cv<decltype(TS::value)>::typesize_t, TS::value>