What is the difference between the C++03's explicit template's instantiation definition and C++11's explicit template's instantiation declaration ?
What I mean is why the instantiation definition is not enough to prevent the compiler from generating implementation for other types ? What is wrong in the below example: imagine I split up the template declaration and definition into two separate files:
A.h
#pragma once template<typename T> class A { public: A(T t); private: T _t; };
A.cpp
#include "A.h" template<typename T> A<T>::A(T t) : _t(t) {} template class A<int>; // explicit instantiation
main.cpp
#include "A.h" int main() { A<int> a(5); // fine, compiler generates header file, // linker links with implementation from A.cpp file // A<float> b(3.14f); // linker error, as expected }
Is there any compilation time overhead in example above? If I understand correctly, in such case, using explicit instantiation definition in a separate *.cpp file (along with template's implementation) I make the compiler to be unable to implicitly instantiate the template with any other types. As such, why there is a separate syntax for explicit instantiation declaration ?
How can explicit instantiation declaration speed up compilation time, if I had ALREADY hidden the implementation in A.cpp file using explicit instantiation definition, and prevented compiler from generating body for other types. Is the "explicit instantiation declaration" somehow related to "explicit instantiation definition", I mean should I use them both, or these are completely separate features (e.g. explicit instantiation declaration can be used only if explicit instantiation definition has not been used) ?
Am I thinking right, that the explicit instantiation definition is only to trigger error in case no other translation unit instantiates the template using given type?
Implicit instantiation means that the compiler automatically generates the concrete function or class for the provided template arguments. In general, the compiler also deduces the template arguments from the function's arguments. In C++17, the compiler can also deduce the template arguments for class templates.
In order for any code to appear, a template must be instantiated: the template arguments must be provided so that the compiler can generate an actual class (or function, from a function template).
To instantiate a template class explicitly, follow the template keyword by a declaration (not definition) for the class, with the class identifier followed by the template arguments. template class Array<char>; template class String<19>; When you explicitly instantiate a class, all of its members are also instantiated.
cpp, there are two instantiations: template class B<int> and B<float>.
When you put an explicit instantiation definition in the file A.cpp
, how is the compiler supposed to know it's there when compiling main.cpp
? The answer is that it can't, so it would still instantiate the templates used in main.cpp
, and in your case using the explicit instantiation definition is useless and doesn't help.
A declaration of an explicit instantiation says to the compiler "do not bother instantiating this template, I will do so myself, somewhere else in the program", and the definition is what fulfils that promise.
The explicit instantiation must be defined exactly once, in only one file, but it can be declared multiple times in different files. This is nothing unique to templates, in C and C++ the same rules apply to (non-inline) functions: you can declare them multiple times in different files (usually by putting the declaration in a header) and then you must define the function exactly once, in one file.
So to make your example work properly you should add a declaration in A.h
:
extern template class A<int>; // explicit instantiation declaration
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With