Title
tuple_size<const T> specialization is not SFINAE compatible and breaks decomposition declarations
Status
c++17
Section
[tuple.helper]
Submitter
Richard Smith

Created on 2016-08-15.00:00:00 last changed 90 months ago

Messages

Date: 2016-11-14.00:32:31

Proposed resolution:

This wording is relative to N4606.

  1. Edit [tuple.helper] as follows:

    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>;
    

    -4- Let TS denote tuple_size<T> of the cv-unqualified type T. If the expression TS::value is well-formed when treated as an unevaluated operand, tThen each of the three templates shall meet the UnaryTypeTrait requirements (20.15.1) with a BaseCharacteristic of

    integral_constant<size_t, TS::value>
    

    Otherwise, they shall have no member value.

    Access checking is performed as if in a context unrelated to TS and T. Only the validity of the immediate context of the expression is considered. [Note: The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the "immediate context" and can result in the program being ill-formed. — end note]

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

Date: 2017-02-02.00:41:18

[ 2016-10 Telecon ]

Alisdair to add his concerns here before Issaquah. Revisit then. Status to 'Open'

Date: 2016-09-14.00:00:00

[ 2016-09-14 Geoffrey provides wording ]

Date: 2016-09-09.00:00:00

[ 2016-09-09 Issues Resolution Telecon ]

Geoffrey to provide wording

Date: 2016-09-15.00:00:00

[ 2016-09-05, Daniel comments ]

This is partially related to LWG 2446.

Date: 2016-08-15.00:00:00

Consider:

#include <utility>

struct X { int a, b; };
const auto [x, y] = X();

This is ill-formed: it triggers the instantiation of std::tuple_size<const X>, which hits a hard error because it tries to use tuple_size<X>::value, which does not exist. The code compiles if <utility> (or another header providing tuple_size) is not included.

It seems that we either need a different strategy for decomposition declarations, or we need to change the library to make the tuple_size partial specializations for cv-qualifiers SFINAE-compatible.

The latter seems like the better option to me, and like a good idea regardless of decomposition declarations.

History
Date User Action Args
2017-07-30 20:15:43adminsetstatus: wp -> c++17
2016-11-14 00:33:00adminsetstatus: immediate -> wp
2016-11-14 00:32:31adminsetstatus: open -> immediate
2016-10-10 20:46:47adminsetmessages: + msg8555
2016-10-10 20:46:47adminsetstatus: new -> open
2016-09-28 18:54:44adminsetmessages: + msg8527
2016-09-28 18:54:44adminsetmessages: + msg8526
2016-09-12 04:36:33adminsetmessages: + msg8511
2016-09-05 19:08:42adminsetmessages: + msg8497
2016-08-15 00:00:00admincreate