- Overview
- Table of Contents
- Special Member Functions: Constructors, Destructors, and the Assignment Operator
- Operator Overloading
- Memory Management
- Templates
- Namespaces
- Time and Date Library
- Streams
- Object-Oriented Programming and Design Principles
- The Standard Template Library (STL) and Generic Programming
- Exception Handling
- Runtime Type Information (RTTI)
- Signal Processing
- Creating Persistent Objects
- Bit Fields
- New Cast Operators
- Environment Variables
- Variadic Functions
- Pointers to Functions
- Function Objects
- Pointers to Members
- Lock Files
- Design Patterns
- Dynamic Linking
- Tips and Techniques
- Five Things You Need to Know About C++11 Unions
- A Tour of C99
- A Tour of C1X
- C++0X: The New Face of Standard C++
- Reference Wrapper
- The Performance Technical Report
- auto for the People
- Ironing Templates' Syntactic Wrinkles
- Visual C++ Becomes ISO Compliant
- A Garbage Collector for C++
- C99 Core Features in C++0X
- The
shared_ptrClass - The shared_ptr Class, II
- Lambda Expressions and Closures, Part I
- Lambda Expressions and Closures, Part II
- Lambda Expressions and Closures, Part III
- The Type Traits Library, Part I
- The Type Traits Library, Part II
- The Type Traits Library, Part III
- finally Revisited
- The Any Library
- The nullptr Keyword Proposal
- Delegating Constructors
- The Explicit Conversion Operators Proposal
- Conditionally-Supported Behavior
- The weak ptr Class Template, Part I
- The weak ptr Class Template, Part II
- POD Types Revisited
- The rvalue Reference Proposal, Part I
- The rvalue Reference Proposal, Part II
- Proposal for New String Algorithms
- Concepts, Part I
- Concepts, Part II
- constexpr: Generalized Constant Expressions
- The constexpr Proposal: Constructors
- Strongly-Typed enum Types
- C++09: The Road Ahead
- C++09: Proposals by Statuses
- Changing Undefined Behavior to Diagnosable Errors
- New Character Types
- The __func__ Predeclared Identifier is Coming to C++
- Static Assertions
- The extern template Proposal
- Variadic Templates, Part I
- Variadic Templates, Part II
- Variadic Templates, Part III -- Critique
- Using unique_ptr, Part I
- Using unique_ptr, Part II
- Unrestricted Unions, Part I
- Unrestricted Unions, Part II
- Unrestricted Unions, Part III
- Types With No Linkage as Template Arguments
- New Initialization Syntax
- Initializer Lists and Sequence Constructors
- New Standard Library Algorithms
- Class Member Initializers
- Inheriting Constructors
- Introducing Attributes
- The Removal of Concepts From C++0x
- The Future of C++0x, Part I
- The Future of C++0X, Part II
- The Debate About Attributes, Part I
- The Debate About Attributes, Part II
- The Debate About Attributes, Part III
- The Debate About Attributes, Part IV
- Forward Declarations of Enum Types
- The SCARY Iterators Proposal, Part I
- The SCARY Iterators Proposal, Part II
- Heading for Deprecation: export, Exception Specification and register
- The Rejection of the Unified Function Syntax Proposal
- Rvalue References as Object Members
- FCD Approved
- The Debate on noexcept, Part I
- The Debate on noexcept, Part II
- The Debate on noexcept, Part III
- About-face -- [[Attributes]] to Be Replaced with Keywords
- Will Delegating Constructors Be Removed From C++0x?
- Rvalue References: Past, Present and Future, Part I
- Rvalue References: Past, Present and Future, Part II
- Rvalue References: Past, Present and Future, Part III
- A Move in the Right Direction, Part I
- A Move in the Right Direction, Part II
- New Keywords for Inheritance Control, Part I
- New Keywords for Inheritance Control, Part II
- FDIS Approved
- C++0x Concurrency
- The Reflecting Circle
- We Have Mail
- The Soapbox
- Numeric Types and Arithmetic
- Careers
- Locales and Internationalization
The extern template Proposal
Last updated Jun 1, 2007.
Unlike the controversy of exported templates, whose de facto status is still uncertain, extern templates are a new core language feature accepted into the Working Paper of C++09 and are here to stay. Find out what extern templates are, what they're good for and how they are used.
The Problem
In many C++ projects and libraries, a common technique is used for implementing automatic instantiation, namely: the compiler instantiates a function in each translation unit in which that function is referenced. Next, the linker eliminates redundant copies of the said instantiation. Thus, multiple .obj files of the same program may contain the object code of the same template specialization, say
swap(int&, int&);
During linkage, the linker removes all redundant copies of swap(int&, int&) from the program, resolving all references to this specialization to a single implementation. This process of removing redundant copies of the same specialization is both slow and imperfect. In some cases, the linker can't eliminate every redundant copy from the resulting executable. As a result, you still get duplicate instances of the same specialization within the same program (hence, a bloated executable file), not to mention the longer compilation time required for generating the object code for the same specialization in multiple object files.
A number of implementations overcome this problem by using extern declarations for templates. This technique was originally introduced as a non-standard extension. In April 2003, it was proposed as new C++09 feature. After a few revisions, this proposal became document number N1987 which was incorporated into the Working Paper recently.
extern Templates
Recall that a C++98 explicit template instantiation consists of the keyword template followed by a template declaration. For example, to explicitly instantiate every member function of std::vector<int>, you can use the following explicit instantiation directive:
template vector<int>; //instantiate every member function of vector<int>
When the compiler sees this directive, it generates every member function of vector<int>not just the member functions that are directly referred to in the current translation unit (however, member functions inherited from base class(es) are not generated). By contrast, the following code (which uses no explicit instantiation directives):
void fun()
{
vector<int> vi;
}
Causes the compiler to generate only two member functions of vector<int>the default constructor and the destructor.
The same rule applies to function templates and member functions of a class templateyou can explicitly instantiate in the following manner:
template void swap<char&, char&>; template void std::vector<int>::push_back(const int&); //instantiate only push_back() template std::vector<double>;//instantiate every member function of vector<double>
The extern templates proposal splits explicit template instantiations into two new categories:
- Explicit instantiation definition
- Explicit instantiation declaration
The C++98 explicit template instantiations that I've just demonstrated are now considered explicit instantiation definitions. When the compiler encounters an explicit instantiation definition, it is forced to generate the code for it. By contrast, an explicit instantiation declaration has the following form:
extern template template-declaration;
In other words, an explicit instantiation preceded by extern template is an explicit instantiation declaration. Examples:
extern template void swap<char&, char&>; extern template void std::vector::push_back(const int&); extern template std::vector<double>;
When the compiler encounters an extern template directive, it suppresses the generation of code for that particular specialization. However, an explicit instantiation of the entity must appear in another translation unit, or later in the same translation unit. An explicit instantiation definition of a given entity shall appear at most once in the program.
In this respect, extern template works very much like extern declarations of a data object: the extern declaration doesn't instantiate the declared object; that object still needs to be defined elsewhere in the program.
extern template Rules
The extern template proposal differs in some aspects from current implementations that support this feature. While some compilers use extern template declarations as a means for providing greater control over the point of instantiation of a template, this proposal provides no such guarantees. The authors also propose the following rules:
- An extern template directive may not name a static function (it may, however, name a static class member).
- An extern template directive that names a class applies to the members of the class, not the class itself. If the class includes nested classes, the extern template directive also applies to the members of the nested class, recursively.
- If a translation unit contains both an explicit instantiation declaration and an explicit instantiation definition, the definition shall appear after the declaration.
extern template and inline
Some existing implementations use extern template directives to control the instantiation of inline functions. The proposal however makes no such guarantees. It only says that "implementations are encouraged to suppress out-of-line copies of inline functions that were declared with extern template." Such inline functions are still instantiated thoughotherwise they cannot be inlined.



