This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 113d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-03-20


488. Local types, overload resolution, and template argument deduction

Section: 13.10.3  [temp.deduct]     Status: CD1     Submitter: Mark Mitchell     Date: 24 Nov 2004

[Voted into the WP at the June, 2008 meeting as paper N2657.]

It is not clear how to handle the following example:

    struct S {
        template <typename T> S(const T&);
    };
    void f(const S&);
    void f(int);
    void g() {
        enum E { e };
        f(e);    // ill-formed?
    }

Three possibilities suggest themselves:

  1. Fail during overload resolution. In order to perform overload resolution for the call to f, the declaration of the required specialization of the S constructor must be instantiated. This instantiation uses a local type and is thus ill-formed (13.4.2 [temp.arg.type] paragraph 2) , rendering the example as a whole ill-formed, as well.

  2. Treat this as a type-deduction failure. Although it is not listed currently among the causes of type-deduction failure in 13.10.3 [temp.deduct] paragraph 2, it could plausibly be argued that instantiating a function declaration with a local type as a template type-parameter falls under the rubric of “If a substitution in a template parameter or in the function type of the function template results in an invalid type” and thus should be a type-deduction failure. The result would be that the example is well-formed because f(const S&) would be removed from the list of viable functions.

  3. Fail only if the function selected by overload resolution requires instantiation with a local type. This approach would require that the diagnostic resulting from the instantiation of the function type during overload resolution be suppressed and either regenerated or regurgitated once overload resolution is complete. (The example would be well-formed under this approach because f(int) would be selected as the best match.)

(See also issue 489.)

Notes from the April, 2005 meeting:

The question in the original example was whether there should be an error, even though the uninstantiable template was not needed for calling the best-matching function. The broader issue is whether a user would prefer to get an error or to call a “worse” non-template function in such cases. For example:

    template<typename T> void f(T);
    void f(int);
    void g() {
        enum E { e };
        f(e);    // call f(int) or get an error?
    }

It was observed that the type deduction rules are intended to model, albeit selectively, the other rules of the language. This would argue in favor of the second approach, a type-deduction failure, and the consensus of the group was that the incremental benefit of other approaches was not enough to outweigh the additional complexity of specification and implementation.

Proposed resolution (October, 2005):

Add a new sub-bullet following bullet 3, sub-bullet 7 ("Attempting to give an invalid type to a non-type template parameter") of 13.10.3 [temp.deduct] paragraph 2:

Additional note (December, 2005):

The Evolution Working Group is currently considering an extension that would effectively give linkage to some (but perhaps not all) types that currently have no linkage. If the proposed resolution above is adopted and then later a change along the lines that the EWG is considering were also adopted, the result would be a silent change in the result of overload resolution, because the newly-acceptable specializations would become part of the overload set. It is not clear whether that possibility is sufficient reason to delay adoption of this resolution or not.

Notes from the April, 2007 meeting:

The Evolution Working Group is now actively pursuing an extension that would allow local and/or nameless types to be used as template arguments, so this resolution will be held in abeyance until the outcome of that proposal is known.

Notes from the June, 2008 meeting:

Paper N2657, adopted at the Sophia Antipolis (June, 2008) meeting, removed the restriction against local and unnamed types as template parameters. The example is now well-formed.