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 ... 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: Here is an example where a qualification conversion applies... Change 13.10.3.6 [temp.deduct.type] paragraph 8 as follows: where 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 T s, i s, or TT s,
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 . —end example] Change 13.10.3.6 [temp.deduct.type] paragraph 19 as follows: Add the following as a new section preceding
C.3.8 [diff.cpp20.library]:
Affected subclause: 13.10.3.6 [temp.deduct.type] [Example 1:
—end example]
and, the return
type, and its exception specification.
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
}
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:
(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 .
[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
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: ...
C.1.4 Clause 13: templates
[diff.cpp20.temp]
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++.
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.
}
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.
[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.