Title
Can a templated constructor be explicitly instantiated or specialized?
Status
cd5
Section
13.10.2 [temp.arg.explicit]
Submitter
Mark Mitchell

Created on 2006-05-19.00:00:00 last changed 20 months ago

Messages

Date: 2019-02-15.00:00:00

Proposed resolution (February, 2019):

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

  2. 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-arguments in the same way as template-arguments are specified in uses of a class template specialization. [Example:
  3. Add the following as a new paragraph following 13.10.2 [temp.arg.explicit] paragraph 1:

  4. 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]).
Date: 2018-10-15.00:00:00

Notes from the October, 2018 teleconference:

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

Date: 2020-12-15.00:00:00

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 <typename T>
    C(const T &) {}
  };
  template C::C<double>(const double &);

with some accepting and some rejecting.

Date: 2006-10-15.00:00:00

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.

Date: 2019-02-15.00:00:00

[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-arguments 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-specifiers (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?
History
Date User Action Args
2020-12-15 00:00:00adminsetmessages: + msg6422
2020-12-15 00:00:00adminsetmessages: + msg6421
2020-12-15 00:00:00adminsetmessages: + msg6420
2020-12-15 00:00:00adminsetstatus: open -> cd5
2006-11-05 00:00:00adminsetmessages: + msg1422
2006-05-19 00:00:00admincreate