CWG Issue 2355 (original) (raw)
This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 117a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-04-13
2355. Deducing _noexcept-specifier_s
Section: 13.10.3.6 [temp.deduct.type]Status: CD6Submitter: John SpicerDate: 2017-09-06
[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 void f1(void ()() noexcept(E)); template struct A { }; template void f2(void ()(A) noexcept(B));
void g1(); void g2() noexcept; void g3(A);
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 Pand A have one of the following forms:
Tcvopt T
T*
T&
T&&
T_opt_[integer-constanti_opt_]template-name (where template-name refers to a class template)type(T)T()T_opt_(T_opt_) noexcept(i_opt_)T type::*type T::*T_opt_ T_opt_::*T (type::*)()type (T::*)()type (type::*)(T)type (T::*)(T)T (type::*)(T)T (T::*)()T (T::*)(T)_type_[i]template-name (where template-name refers to a class template)TT_opt_
TT_opt_
TT_opt_
TT_opt_<>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.
- T_opt_ represents a type or parameter-type-list that either satisfies these rules recursively, is a non-deduced context in P orA, or is the same non-dependent type in Pand A,
- TT_opt_represents either a class template or a template template parameter,
- i_opt_ represents an expression that either is an i, is value-dependent in Por A, or has the same constant value in P andA, and
- noexcept(i_opt_) 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 ani_opt_ above.
[Note: If a type matches such a form but contains no Ts, is, or TTs, deduction is not possible. —_end note_]
Similarly, represents template argument lists where at least one argument contains a T, represents template argument lists where at least one argument contains an i and <> represents template argument lists where no argument contains a Tor 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 struct A { }; template struct B; template<auto X, void (*F)() noexcept(X)> struct B { A ax; }; void f_nothrow() noexcept; B 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 , 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. IfP 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 includesnoexcept(i) and the type of i is notbool, 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 struct A { }; template void f(void (*)(A) noexcept(B)); void g(A) noexcept; void h() { f(g); // ill-formed; previously well-formed. }
—_end example_]