Why isn't just extern template int foo<42>() sufficient |
Firstly, there's not enough information in the explicit instantiation declaration alone to determine which template instantiation is being declared.
For example, the primary template could have default template arguments:
1 2
|
// template <int N, int = 1> int foo();
extern template int foo<42>();
|
If the first line was un-commented, the second line would declare an explicit instantiation of
template int foo<42, 1>();
Secondly, and more importantly, unlike
generics in other languages, C++ templates are purely a meta-programming facility. They do not exist in the compiled code. They only tell the compiler how to write code for you.
The function template
template <int N> int bar() { std::cout << N << '\n'; }
Exists only at compile-time as an instruction to the compiler. The function template tells the compiler how to write a set of independent functions (incl.
template int bar<1>() and
template int bar<251>()) for the programmer
on demand.
If I try to call
bar<2>() in my source code, the compiler must locate the corresponding function template, which is
template <int N> int bar() { std::cout << N << '\n'; }
and substitute N with 10 to produce this actual function
template int bar<10>() { std::cout << 10 << '\n'; }
which can then be called. (This process is called implicit instantiation.)
The compiler must be able to "see" the template's definition to generate code. This means the template's definition must be visible from the same translation unit which instantiates the template. See also this stack overflow answer:
https://stackoverflow.com/q/495021/2085046