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):

  1. 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:

  1. 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...

  1. 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: T cvopt T
T*
T&
T&&
T_opt_[integer-constant i_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.

[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.

  1. 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_]

  1. 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: ...

  1. 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_]