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

2024-11-11


2138. Explicit member specialization vs implicit instantiation

Section: 13.9.4  [temp.expl.spec]     Status: NAD     Submitter: Richard Smith     Date: 2015-06-11

It is not clear whether the following common practice is valid by the current rules:

   // foo.h
   template<typename T> struct X {
    int f(); // never defined
   };

   // foo.cc
   #include "foo.h"
   template<> int X<int>::f() { return 123; }

   // main.cc
   #include "foo.h"
   int main() { return X<int>().f(); }

Relevant rules include Clause 13 [temp] paragraph 6,

A function template, member function of a class template, variable template, or static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated (13.9.2 [temp.inst]) unless the corresponding specialization is explicitly instantiated (13.9.3 [temp.explicit]) in some translation unit; no diagnostic is required.

13.9.2 [temp.inst] paragraph 2,

Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist...

and 13.9.4 [temp.expl.spec] paragraph 6:

If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required. An implicit instantiation is never generated for an explicit specialization that is declared but not defined.

The intent appears to be that the reference in main.cc violates two rules: it implicitly instantiates something for which no definition is provided and that is not explicitly instantiated elsewhere, and it also causes an implicit instantiation of something explicitly specialized in another translation unit without a declaration of the explicit specialization.

Rationale (March, 2016):

As stated in the analysis, the intent is for the example to be ill-formed, no diagnostic required.