CWG Issue 581 (original) (raw)

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

2025-11-05


581. Can a templated constructor be explicitly instantiated or specialized?

Section: 13.10.2 [temp.arg.explicit]Status: CD5Submitter: Mark MitchellDate: 19 May 2006

[Accepted as a DR at the February, 2019 meeting.]

Although it is not possible to specify a constructor's template arguments in a constructor invocation (because the constructor has no name but is invoked by use of the constructor's class's name), it is possible to “name” the constructor in declarative contexts: per 6.5.5.2 [class.qual] paragraph 2,

In a lookup in which the constructor is an acceptable lookup result, if the nested-name-specifier nominates a class C, and the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C ( Clause 11 [class]), the name is instead considered to name the constructor of class C... Such a constructor name shall be used only in the declarator-id of a declaration that names a constructor.

Should it therefore be possible to specify _template-argument_s for a templated constructor in an explicit instantiation or specialization? For example,

template <int dim> struct T {};
struct X {
  template <int dim> X (T<dim> &) {};
};

template X::X<> (T<2> &);

If so, that should be clarified in the text. In particular, 11.4.5 [class.ctor] paragraph 1 says,

Constructors do not have names. A special declarator syntax using an optional sequence of _function-specifier_s (9.2.3 [dcl.fct.spec]) followed by the constructor's class name followed by a parameter list is used to declare or define the constructor.

This certainly sounds as if the parameter list must immediately follow the class name, with no allowance for a template argument list.

It would be worthwhile in any event to revise this wording to utilize the “considered to name” approach of 6.5.5.2 [class.qual]; as it stands, this wording sounds as if the following would be acceptable:

struct S {
    S();
};
S() { }    // qualified-id not required?

Notes from the October, 2006 meeting:

It was observed that explicitly specifying the template arguments in a constructor declaration is never actually necessary because the arguments are, by definition, all deducible and can thus be omitted.

Additional notes, October, 2018:

The wording in 13.10.2 [temp.arg.explicit] paragraph 1 refers to a “function name,” which constructors do not have, and so presumably the current wording does not permit an explicit specialization of a constructor template. Nevertheless, there is implementation divergence in the treatment of an example like:

class C { template C(const T &) {} }; template C::C(const double &);

with some accepting and some rejecting.

Notes from the October, 2018 teleconference:

The consensus was to allow template arguments on the constructor name but not something like C::C::f.

Proposed resolution (February, 2019):

  1. Cbange 13.10.2 [temp.arg.explicit] paragraph 1 as follows:

Template arguments can be specified when referring to a function template specialization that is not a specialization of a constructor template by qualifying the function template name with the list of _template-argument_s in the same way as _template-argument_s are specified in uses of a class template specialization. [Example:

  1. Add the following as a new paragraph following 13.10.2 [temp.arg.explicit] paragraph 1:

Template arguments shall not be specified when referring to a specialization of a constructor template (11.4.5 [class.ctor], 6.5.5.2 [class.qual]).