-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CWG2896 [temp.deduct] Deducing template arguments from function declarations with noexcept-specifiers #537
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: