Created on 2023-12-15.00:00:00 last changed 8 months ago
Additional notes (April, 2024)
The phrasing "an explicit specialization of a function" does not make sense.
Possible resolution:
Add a new paragraph before 13.9.4 [temp.expl.spec] paragraph 8 as follows:
An explicit specialization that declares a function shall not have a trailing requires-clause (9.3.1 [dcl.decl.general]). [ Example:
template<typename T> concept C = sizeof(T) <= sizeof(int); template<typename T> struct A { template<typename U> void f(U) requires C<U>; template<> void f(char); // OK template<> void f(short) requires (sizeof(T) >= 1); // error: trailing requires-clause not allowed }; template<> template<typename U> void A<int>::f(U) requires C<U> {} // OK, explicit specialization is a template template<> template<> void A<short>::f(int) requires C<int> {} // error: trailing requires-clause for a declaration of a non-templated function-- end example ]
The placement of explicit specialization declarations for function templates ...
Add another example at the end of 13.9.4 [temp.expl.spec] paragraph 15 as follows:
[ Example:
template<typename T> struct D { template<typename U> static constexpr int f(U); // #1 template<typename U> static constexpr int f(U) requires (sizeof(T) == 1); // #2 template<> constexpr int f(int) // #3 { return 1; } }; template<> template<typename U> constexpr int D<signed char>::f(U) requires (sizeof(signed char) == 1) // #4 { return 0; } static_assert(D<char>::f(0) == 1); // overload resolution selects #2; #3 is a specialization for #2 static_assert(D<char[2]>::f(0) == 1); // overload resolution selects #1; #3 is a specialization for #1 static_assert(D<signed char>::f(0) == 1); // overload resolution selects #2; #3 is a specialization for #2 static_assert(D<signed char>::f(0.0) == 0); // overload resolution selects #2; #4 is a specialization for #2-- end example ]
Proposed resolution (reviewed by CWG 2024-03-01) [SUPERSEDED]:
Add a new paragraph before 13.9.4 [temp.expl.spec] paragraph 8 as follows:
An explicit specialization of a function shall not have a trailing requires-clause (9.3.1 [dcl.decl.general]). [ Example:
template<typename T> concept C = sizeof(T) <= sizeof(int); template<typename T> struct A { template<typename U> void f(U) requires C<U>; template<> void f(char); // OK template<> void f(short) requires (sizeof(T) >= 1); // error: trailing requires-clause not allowed }; template<> template<typename U> void A<int>::f(U) requires C<U> {} // OK, explicit specialization is a template-- end example ]
The placement of explicit specialization declarations for function templates ...
Add another example at the end of 13.9.4 [temp.expl.spec] paragraph 15 as follows:
[ Example:
template<typename T> struct D { template<typename U> static constexpr int f(U); // #1 template<typename U> static constexpr int f(U) requires (sizeof(T) == 1); // #2 template<> constexpr int f(int) // #3 { return 1; } }; template<> template<typename U> constexpr int D<signed char>::f(U) requires (sizeof(signed char) == 1) // #4 { return 0; } static_assert(D<char>::f(0) == 1); // overload resolution selects #2; #3 is a specialization for #2 static_assert(D<char[2]>::f(0) == 1); // overload resolution selects #1; #3 is a specialization for #1 static_assert(D<signed char>::f(0) == 1); // overload resolution selects #2; #3 is a specialization for #2 static_assert(D<signed char>::f(0.0) == 0); // overload resolution selects #2; #4 is a specialization for #2-- end example ]
(From submission #482.)
Consider:
template<typename T>
concept C = sizeof(T) > sizeof(char);
template<typename T>
concept D = sizeof(T) > sizeof(int) ;
template<typename T>
struct A
{
template<typename U>
constexpr int f(U) requires C<U> { return 0; }
template<>
constexpr int f(int) requires D<T> { return 1; }
};
static_assert(A<int>().f(0) == 0); // #1
There is substantial implementation variance: GCC does not allow explicit specializations of function templates at class scope (contrary to the rule change introduced by issue 727), clang rejects them if a trailing-requires-clause is present, and EDG accepts, but ignores the constraint, causing #1 to fail.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-04-12 20:49:59 | admin | set | messages: + msg7663 |
2024-02-03 00:15:40 | admin | set | status: open -> review |
2024-01-29 22:07:02 | admin | set | messages: + msg7581 |
2023-12-15 00:00:00 | admin | create |