Instant point
templates will be created upon actual use
Not really, but rude. The exact instantiation point is a little subtle, and I pass you to the section called The Creation Point in the wonderful book of Vandevoord / Josuttis.
However, compilers do not necessarily implement the POI correctly: C ++ / 41995 error: Invalid instantiation point for function template
Partial Instance
templates will be created upon actual use
This is partially correct. This is true for function templates, but only those member functions are instantiated for class templates. The following is the correct code:
#include <iostream> template <typename> struct Foo { void let_me_stay() { this->is->valid->code. get->off->my->lawn; } void fun() { std::cout << "fun()" << std::endl; } }; int main () { Foo<void> foo; foo.fun(); }
let_me_stay() checked syntactically (and the syntax is correct there), but not semantically (i.e. it is not interpreted).
Biphasic search
However, only dependent code is interpreted later; it is clear that inside Foo<> , this depends on the exact identifier of the template with which Foo<> , so we deferred the error checking Foo<>::let_me_alone() until the instance was created.
But if we do not use something that depends on a specific instance, the code should be good. Therefore, not :
$ cat non-dependent.cc template <typename> struct Foo { void I_wont_compile() { Mine->is->valid->code. get->off->my->lawn; } }; int main () {}
Mine is a completely unknown character to the compiler, unlike this , for which the compiler could determine its instance dependency.
The key point here is that C ++ uses a two-phase search model, where it checks for independent code in the first phase and the semantic verification of the dependent code is performed in the second phase (and the instant of creation) (this is also often a misunderstood or unknown concept, many programmers C ++ suggests that the templates are not processed at all until the instance is created, but this is only a myth coming from, ..., Microsoft C ++).
Full implementation of class templates
The definition of Foo<>::let_me_stay() worked because error checking was deferred to a later version, like the this pointer, which depends. Except when you used
explicit instances
cat > foo.cc #include <iostream> template <typename> struct Foo { void let_me_stay() { this->is->valid->code. get->off->my->lawn; } void fun() { std::cout << "fun()" << std::endl; } }; template struct Foo<void>; int main () { Foo<void> foo; foo.fun(); } g++ foo.cc error: error: 'struct Foo<void>' has no member named 'is'
Template definitions in different translation units
When you explicitly create an instance, you create the instance explicitly. And make all the characters visible to the linker, which also means that the template definition can be in different translation units:
$ cat A.cc template <typename> struct Foo { void fun();
However, you must explicitly create an instance for all template arguments, otherwise
$ cat A.cc template <typename> struct Foo { void fun();
A small note about two-phase search: whether the compiler really implements two-phase search is not dictated by the standard. However, to be compatible, it must work as if it were being executed (just like adding or multiplying does not have to be done using CPU instructions or adding or multiplying.