2

Standard says that template names have external linkage.

My question is: "Why isn't there a linker error when I declare the same templates in two .cpp files and compile this files together?"

Global functions names have external linkage like templates names. That's why I suggest that they should have similar behavior. But as for functions there is nothing strange and the linker produces an error, but as for templates somehow there is no error.

temp_1.cpp

#include <iostream>

// error because of external linkage
// void eq_f(){}


template<class T>
void my_func() {
    std::cout << "1!";
}

temp_2.cpp

#include <iostream>

// external linkage
// void eq_f(){}

template<class T>
void my_func() {
    std::cout << "2!";
}

int main() {
    my_func<int>();
    return 0;
}

command:

clang++ temp_1.cpp temp_2.cpp -std=c++17
Gusev Slava
  • 2,136
  • 3
  • 21
  • 26
  • 1
    read this : https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – JeJo May 10 '18 at 10:12
  • @SaufenmitProgramming ok, thanks. try to find answer. – Gusev Slava May 10 '18 at 10:13
  • You might also want to read what templates actually do, because right now, `temp_1.o` only has some static constructors because of ``, there is no `my_func` in there. – Rakete1111 May 10 '18 at 10:15
  • @Rakete1111 this line "external linkage ... names of all templates not listed above " from cppref confused me – Gusev Slava May 10 '18 at 10:20

1 Answers1

2

temp_1.cpp doesn't produce any code because template is compiled for the implementations, the only class the compiler can find for the main is in temp_2.cpp.

That's why you don't get any error.

It is somehow can be compared to a macro: the template class is like the #define, the implementations is like using the macro in the code, at the end of the cpp the "macro" is undefined, only the implementations of it are left.

EDIT:

As I wrote above, the template itself doesn't generate any type, that's why it can't be linked. the type definition is when you use the teplate with a typedef or variable declaration.

for example: template<class T> class vector is a template class, it doesn't make any type definition and doesn't produce any code.

When you use it : vector<int> vInt; or typedef vector<int> vInt_t the class will compiled only for class T=int if you use it again for other type it will be compiled again for that type too.

only used templated type may have a linkage, means it will be the same type when you define it again. the type vector<int> may have external linkage, (means can be return from library or dll, etc.)

SHR
  • 7,940
  • 9
  • 38
  • 57