Reputation: 143
In the following program we take the address of a function template for which no definition is available.
template <typename T>
void fun(T);
int main()
{
void (*funptr)(int) = fun;
}
I was taught that the compiler decides to instantiate a function template when its address is taken, but the above program compiles just fine (of course the linker will throw an error that it cannot find the definition for fun
). Compilation only fails if we use explicit instantiation:
template <typename T>
void fun(T);
template void fun<int>(int);
int main()
{}
Does this mean that only compiling the second source code instantiates the function template? Or is it also instantiated in the first but I'm missing something?
Thanks in advance!
Upvotes: 3
Views: 443
Reputation: 10596
When you take an address or call the function, the compiler leaves a reference to its instantiation. If there was the template definition, it would've been instantiated to satisfy that reference. But since the template definition is not provided, it cannot be actually instantiated, so only the unresolved reference is left. That unresolved reference must be resolved at the linking stage by a different object file, which contains the necessary instantiation. This means that the instantiation must have happened when that other object file was compiled.
When you explicitly instantiate the function template, the template definition must be present (otherwise, there's nothing to instantiate). Since you haven't provided one, you get an error at the compilation stage, rather than linking.
Upvotes: 8