This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
[Accepted at the July, 2022 meeting.]
The list of deducible forms in 13.10.3.6 [temp.deduct.type] paragraph 8 does not include the ability to deduce the value of the constant in a noexcept-specifier, although implementations appear to allow it.
Notes from the April, 2018 teleconference:
Although this appears to be an obvious omission, CWG felt that EWG should weigh in on whether this capability should be supported or not.
EWG guidance (January, 2021):
Modify the Standard such that the value of a constant in a noexcept-specifier can be deduced. See vote.
Proposed resolution (June, 2022):
Change 13.10.3.6 [temp.deduct.type] paragraph 3 as follows:
A given type P can be composed from a number of other types, templates, and non-type values:
A function type includes the types of each of the function parameters
and, the return type, and its exception specification....
Add the following to Example 3 in 13.10.3.6 [temp.deduct.type] paragraph 7:
Here is an example where two template arguments are deduced from a single function parameter/argument pair...
Here is an example where the exception specification of a function type is deduced:
template <bool E> void f1(void (*)() noexcept(E)); template<bool> struct A { }; template<bool B> void f2(void (*)(A<B>) noexcept(B)); void g1(); void g2() noexcept; void g3(A<true>); void h() { f1(g1); // OK: E is false f1(g2); // OK: E is true f2(g3); // error: B deduced as both true and false }Here is an example where a qualification conversion applies...
Change 13.10.3.6 [temp.deduct.type] paragraph 8 as follows:
A template type argument T, a template template argument TT, or a template non-type argument i can be deduced if P and A have one of the following forms:
Tcvopt T
T*
T&
T&&
Topt[integer-constantiopt]
template-name<T> (where template-name refers to a class template)Topt(Topt) noexcept(iopt)
type(T)
T()
T type::*Topt Topt::*
type T::*
T (type::*)()
type (T::*)()
type (type::*)(T)
type (T::*)(T)
T (type::*)(T)
T (T::*)()
T (T::*)(T)type[i]TTopt<T>
template-name<i> (where template-name refers to a class template)
TTopt<i>
TTopt<TT>
TTopt<>
where
(T) represents a parameter-type-list (9.3.4.6 [dcl.fct]) where at least one parameter type contains a T, and () represents a parameter-type-list where no parameter type contains a T.
Topt represents a type or parameter-type-list that either satisfies these rules recursively, is a non-deduced context in P or A, or is the same non-dependent type in P and A,
TTopt represents either a class template or a template template parameter,
iopt represents an expression that either is an i, is value-dependent in P or A, or has the same constant value in P and A, and
noexcept(iopt) represents an exception specification (14.5 [except.spec]) in which the (possibly-implicit, see 9.3.4.6 [dcl.fct]) noexcept-specifier's operand satisfies the rules for an iopt above.
[Note: If a type matches such a form but contains no Ts, is, or TTs, deduction is not possible. —end note]
Similarly, <T> represents template argument lists where at least one argument contains a T, <i> represents template argument lists where at least one argument contains an i and <> represents template argument lists where no argument contains a T or an i.
Add the following as a new paragraph following 13.10.3.6 [temp.deduct.type] paragraph 14:
The type of N in the type T[N] is std::size_t. [Example 9: ... —end example]
The type of B in the noexcept-specifier noexcept(B) of a function type is bool.
[Example:template<bool> struct A { }; template<auto> struct B; template<auto X, void (*F)() noexcept(X)> struct B<F> { A<X> ax; }; void f_nothrow() noexcept; B<f_nothrow> bn; // OK: type of X deduced as bool—end example]
Change 13.10.3.6 [temp.deduct.type] paragraph 19 as follows:
If P has a form that contains <i>, and if the type of i differs from the type of the corresponding template parameter of the template named by the enclosing simple-template-id, deduction fails. If P has a form that contains [i], and if the type of i is not an integral type, deduction fails.131 If P has a form that includes noexcept(i) and the type of i is not bool, deduction fails.
[Example 12: ...
Add the following as a new section preceding C.2.7 [diff.cpp20.library]:
C.1.4 Clause 13: templates [diff.cpp20.temp] Affected subclause: 13.10.3.6 [temp.deduct.type]
Change: Deducing template arguments from exception specifications.
Rationale: Facilitate generic handling of throwing and non-throwing functions.
Effect on original feature: Valid ISO C++20 code may be ill-formed in this revision of C++.
[Example 1:
template<bool> struct A { }; template<bool B> void f(void (*)(A<B>) noexcept(B)); void g(A<false>) noexcept; void h() { f(g); // ill-formed; previously well-formed. }
—end example]