J L
J L

Reputation: 655

Access checking is performed as if in a context unrelated to T. Only the validity of the immediate context of the expression is considered

The following quote from paragraph 8 of C++17:17.8.2 ([temp.deduct]) is one of the basis of SFINAE:

If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed, with a diagnostic required, if written using the substituted arguments. [ Note: If no diagnostic is required, the program is still ill-formed. Access checking is done as part of the substitution process. — end note ] Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure. [ Note: The substitution into types and expressions can result in effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc. Such effects are not in the “immediate context” and can result in the program being ill-formed. — end note ]

Likewise, the following wording template appears in the C++17 Standard only 6 times (std::tuple_size<cv-qualified T>, std::is_swappable_with<>, std::is_assignable<>, std::is_constructible<>, std::is_convertible<> and std::invoke_result<>):

Access checking is performed as if in a context unrelated to <Type/Args>. Only the validity of the immediate context of the <expression> is considered. [ Note: The {compilation of the expression,evaluation of the initialization, initialization} 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 ]

Specifically, the wording for std::tuple_size<cv-qualified T> comes from a DR with that goal, that is, to make them SFINAE-friendly. However, there is some extra wording before:

If the expression TS::value is well-formed when treated as an unevaluated operand, [...]. Otherwise, they shall have no member value.

I was wondering why this was added too. If it wasn't, and if I understand it correctly, std::tuple_size<X>::value from the DR example would still not exist because that primary template std::tuple_size<> has no specialization for type X. Thus, it could still be a type deduction failure (...?) and SFINAE would still work?

Is this other wording strictly unrelated to SFINAE and only to state when there is no such member named value? Or is it closely related and indeed also necessary to achieve the SFINAE-compatibility?

Upvotes: 0

Views: 83

Answers (0)

Related Questions