0

Assume these two cc files:

0.cc

#include <iostream>

template <class T>
T test(){
 return 5;
}

int main(){
 return test<int>();
}

1.cc

template <class T>
T test(){
 return 5;
}

We compile them with g++ 0.cc 1.cc.

This compiles and runs successfully but if above functions were not templates then we would get a duplicate symbol error during compilation and linking phase.

Why using templates does not generate a link error?

Dan
  • 2,694
  • 1
  • 6
  • 19
  • 2
    You get duplicate symbols when you have **implemented** two functions with the same name. You can however **declare** functions how many times you want. A template isn't an implementation, but a declaration. The actual implementation is created by the compiler. – Ted Klein Bergman Feb 24 '21 at 18:41

1 Answers1

2

Template is not instantiated until it is called in the code. Think of it as a local function to the compiled object.

Therefore, template as such is not exported and is not subject to linking of any kind, as it can't be referenced from another object. Should you be calling template defined in another header, it would still be instantiated in the local object.

W.B.
  • 5,445
  • 19
  • 29
  • That being said, if the functions had different bodies, and both were instantiated, you'd have undefined behavior, but probably no linker error – Mooing Duck Feb 24 '21 at 18:44
  • What if a template is marked as `extern` and its actual definition is in another `cc` file, how does it link then? shouldn't there be exported symbols? – Dan Feb 24 '21 at 18:45
  • @Dan _instantiating_ a template defines some (not all!) of the methods, and the linker will automatically find all template methods that are the same and drop all but one. If they don't match exactly, then your code has undefined behavior, but the compiler/linker won't usually be able to detect it and tell you. – Mooing Duck Feb 24 '21 at 18:47
  • 1
    @MooingDuck So it's kind of similar to how `inline` functions work. If there are multiple of them compiler chooses one, and if their implementation differs we get undefined behaviour. – Dan Feb 24 '21 at 18:48
  • You cannot mark template as extern, as template itself is not a function, it is a definition of a function that only becomes a function once it is called. That's why you define templates in headers, not cc, because compiler needs access to all template code. If course templates can call functions implemented in cc files, but these parts are then linked. – W.B. Feb 24 '21 at 18:49
  • 1
    You can mark templates as extern as of C++11. – Dan Feb 24 '21 at 18:50
  • Yes, scratch that. Imo it's not reliable, as you need to make sure that the template is instantiated (called) somewhere else. – W.B. Feb 24 '21 at 18:52
  • 1
    @W.B.: It works exactly the same as a variable or function declaration. I find it reliable, just rarely useful. – Mooing Duck Feb 24 '21 at 19:16
  • By unreliable (and perhaps that's not the best word I used there) I mean that you have to explicitly instantiate specific types. And then when you want to use the template with another type, you need to change the implementation file (provided you have access to it). So perhaps what I meant was that it is not as flexible. – W.B. Feb 24 '21 at 19:22