-
Notifications
You must be signed in to change notification settings - Fork 7
CWG2896 [temp.deduct] Deducing template arguments from function declarations with noexcept-specifiers #537
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
The noexcept-specifier should also be ignored when deducing template arguments taking the address of a function template, but I'm not sure whether it should be part of this issue. |
…ication as used during partial ordering (#91534) We do not deduce template arguments from the exception specification when determining the primary template of a function template specialization or when taking the address of a function template. Therefore, this patch changes `isAtLeastAsSpecializedAs` such that we do not mark template parameters in the exception specification as 'used' during partial ordering (per [temp.deduct.partial] p12) to prevent the following from being ambiguous: ``` template<typename T, typename U> void f(U) noexcept(noexcept(T())); // #1 template<typename T> void f(T*) noexcept; // #2 template<> void f<int>(int*) noexcept; // currently ambiguous, selects #2 with this patch applied ``` Although there is no corresponding wording in the standard (see core issue filed here cplusplus/CWG#537), this seems to be the intended behavior given the definition of _deduction substitution loci_ in [temp.deduct.general] p7 (and EDG does the same thing).
It is not clear to me why the address-of-function-template case also needs to ignore the exception specification. Also, for the two carve-outs here, do they apply only to a noexcept-specifier on the top level of a function declaration, or also to noexcept-specifiers on function parameters of (e.g.) function pointer type? "Any noexcept-specifier is ignored" sounds very much like the latter, but it seems the former is intended. |
Minor grammar nit:
"consider" should be "considering". |
The phrasing of [except.spec] p13.1 seems to suggest that the exception specification is instantiated only for the (unique) function selected by overload resolution. The address-of-function-template case requires deduction be performed for the candidate templates, which can result in errors outside the immediate context, e.g.: struct A
{
static constexpr bool x = true;
};
template<typename T, typename U>
void f(T, U*) noexcept(T::x); // #1
template<typename T, typename U>
void f(T, U) noexcept(T::y); // #2
void(&g)(A, int*) noexcept = f; Excluding the noexcept-specifier from deduction and partial ordering in this case results in only the exception specification of
Yes, they only apply to a noexcept-specifier on the top level of a function declaration. |
Fixed "considering" and clarified top-level noexcept-specifier. Amended for address-of-function-template case. |
Full name of submitter: Krystian Stasiowski
Reference (section label): [temp.deduct]
Link to reflector thread (if any): N/A
Issue description:
According to [temp.deduct.decl] p1:
Consider the following:
Despite the resolution of CWG2355, the explicit specialization of
f
is rejected by Clang, GCC, EDG, and MSVC because a template argument forB
cannot be deduced from the noexcept-specifier. This approach is arguably correct, as it avoids instantiating the exception specification for all candidate templates (which could render the program ill-formed as the noexcept-specifier excluded from the deduction substitution loci). Moreover, deduction from the noexcept-specifier may not be immediately possible because it hasn't been parsed yet (e.g. for a class scope explicit specialization). The wording should be changed to reflect existing implementation practice.Excluding the noexcept-specifier from deduction when deducing template arguments from a function declaration also necessitates its exclusion from deduction during partial ordering in such contexts, as template parameters only used in the noexcept-specifer would otherwise cause template argument deduction to always fail.
Suggested resolution:
Change [temp.deduct.decl] p1 as follows:
Change [temp.deduct.partial] p3 as follows:
The text was updated successfully, but these errors were encountered: