extern Templates (C++11)

From RAD Studio
Jump to: navigation, search

Go Up to C++11 Features in the Classic Compiler


Attention: This page refers to a C++11 feature in the Classic compiler. The Classic compiler is not recommended: instead it is recommend you use the Clang-enhanced compilers, which support modern C++ including C++11, C++14 and C++17.

BCC32 includes the use of extern templates, which allow you to define templates that are not instantiated in a translation unit. Using extern templates thus reduces both compilation time and the size of the compiled module. This feature is part of the new C++11 standard.

Explicit Instantiation and Declaration

An extern template allows you to declare a template without instantiating it in the translation unit.

To illustrate, the following both creates and instantiates a template:

template <class T>
class MyClass 
{
   // ... various code
}

template class MyClass<int>;
...
MyClass<int> myClass;

The line template class MyClass<int> is an explicit template definition and causes the template to be instantiated explicitly in its code unit, resulting in generating code for the template in that unit. Similarly, the line MyClass<int> myClass; implicitly instantiates the template, also resulting in code generation in the unit. If either of these lines of code are in your unit, the template is instantiated there.

However, suppose you want to have a library in which all instantiations of this template occur, and you want to refer to these instantiations in an executable. To make an explicit template declaration that does not instantiate the template in your code unit, use the following:

extern template class MyClass<int>;

You can then reference the template, but the compiler does not generate code for it in that translation unit.

extern Template Usage

Here are the rules for using extern templates:

  • A template instantiation must either follow an explicit template declaration in that translation unit or be in another translation unit. This is similar to the usual use of extern: the entity referenced must be defined somewhere.
  • An explicit template definition must occur only once in a unit.
  • An explicit template definition must follow an explicit template declaration if both are present in a translation unit.
  • An explicit template declaration can only apply to names of objects, functions, and explicit template instantiations. It may not refer to a static function, but may apply to a static member function.
  • The extern specifier may not be used in declaration of class members or parameters.
  • An explicit template declaration only suppresses code generation if that template has not been instantiated with the same specialization. For instance:
template class MyClass<int>;
...
extern template class MyClass<int>;    // not allowed
extern template class MyClass<float>;  // OK

See Also