Skip to content

CWG2896 [temp.deduct] Deducing template arguments from function declarations with noexcept-specifiers #537

Open
@sdkrystian

Description

@sdkrystian

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:

In a declaration whose declarator-id refers to a specialization of a function template, template argument deduction is performed to identify the specialization to which the declaration refers. Specifically, this is done for explicit instantiations, explicit specializations, and certain friend declarations. This is also done to determine whether a deallocation function template specialization matches a placement operator new. In all these cases, P is the type of the function template being considered as a potential match and A is either the function type from the declaration or the type of the deallocation function that would match the placement operator new as described in [expr.new]. The deduction is done as described in [temp.deduct.type].

Consider the following:

template<bool B>
void f() noexcept(B);

template<>
void f() noexcept;

Despite the resolution of CWG2355, the explicit specialization of f is rejected by Clang, GCC, EDG, and MSVC because a template argument for B 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:

[...] In all these cases, P is the function type of the function template being considered as a potential match and A is either the function type from the declaration or the type of the deallocation function that would match the placement operator new as described in [expr.new]. Any noexcept-specifier is ignored when determining the types of P and A. The deduction is done as described in [temp.deduct.type].

Change [temp.deduct.partial] p3 as follows:

The types used to determine the ordering depend on the context in which the partial ordering is done:

  • In the context of a function call, the types used are those function parameter types for which the function call has arguments.
  • In the context of a call to a conversion function, the return types of the conversion function templates are used.
  • In other contexts the function template's function type outside of the noexcept-specifier is used.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions