Title
Where must export appear?
Status
cd1
Section
Clause [13] [temp]
Submitter
Daveed Vandevoorde

Created on 2001-11-14.00:00:00 last changed 196 months ago

Messages

Date: 2003-04-15.00:00:00

[Voted into WP at April 2003 meeting.]

Date: 2002-10-15.00:00:00

Proposed Resolution (revised October 2002):

Replace Clause 13 [temp] paragraphs 6, 7, and 8 by the following text:

A template-declaration may be preceded by the export keyword. Such a template is said to be exported. Declaring exported a class template is equivalent to declaring exported all of its non-inline member functions, static data members, member classes, member class templates, and non-inline member function templates.

If a template is exported in one translation unit, it shall be exported in all translation units in which it appears; no diagnostic is required. A declaration of an exported template shall appear with the export keyword before any point of instantiation (13.8.4.1 [temp.point]) of that template in that translation unit. In addition, the first declaration of an exported template containing the export keyword must not follow the definition of that template. The export keyword shall not be used in a friend declaration.

Templates defined in an unnamed namespace, inline functions, and inline function templates shall not be exported. An exported non-class template shall be defined only once in a program; no diagnostic is required. An exported non-class template need only be declared (and not necessarily defined) in a translation unit in which it is instantiated.

A non-exported non-class template must 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.

Note: This change also resolves issues 204 and 335.

Date: 2004-09-10.00:00:00

The standard doesn't seem to describe whether the keyword export should appear on exported template declarations that are not used or defined in that particular translation unit.

For example:

  // File 1:
  template<typename T> void f();  // export omitted

  // File 2:
  export template<typename T> void f() {}

  int main() { f<int>(); }

Another example is:

  // File 1:
  struct S {
     template<typename T> void m();
  };

  // File 2:
  struct S {
     template<typename T> void m();
  };

  export template<typename T> void S::m() {}

  int main() {
     S s;
     S.m<int>();
  }

I think both examples should be clarified to be invalid. If a template is exported in one translation unit, it should be declared export in all translation units in which it appears.

With the current wording, it seems that even the following is valid:

  // File 1:
  export template<typename T> void f();  // export effectively ignored

  // File 2:
  template<typename T> void f() {}  // Inclusion model
  void g() { f<int>(); }

  // File 3:
  void g();
  template<typename T> void f() {}  // Inclusion model

  int main() {
     g();
     f<int>();
  }

In fact, I think the declaration in "File 1" could be a definition and this would still satisfy the the requirements of the standard, which definitely seems wrong.

History
Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2003-04-25 00:00:00adminsetmessages: + msg869
2003-04-25 00:00:00adminsetstatus: ready -> wp
2002-11-08 00:00:00adminsetstatus: review -> ready
2002-05-10 00:00:00adminsetmessages: + msg630
2002-05-10 00:00:00adminsetstatus: open -> review
2001-11-14 00:00:00admincreate