2

After reading about templates, I am confused about their compilation. For example, in a header we define a template as -

template<typename T>
class Object {
public:
    Object();
    void hashCode(T& arg){ /* implementation code in header-only. */ }
};

We use this template in two source files - SourceI.cpp & SourceII.cpp by including Object.hpp -

SourceI.cpp

void doSomething()
{
    Object<int> intHasher;
    intHasher.hashCode();
    // Further code...
}

SourceII.cpp

void doNothing()
{
     Object<int> notUsedHere;
     notUsedHere.hashCode();
}

The compile should generate code for the class instantiation for the "int" type. Where will be the code stored for Object<int> type. Or will the code for Object<int>::hashCode() be inlined in all uses?

If the code is not inlined, then won't symbols clash will linking because they would be present in multiple object files?

NOTE - The code is for giving a example and doesn't show any purpose.

Shukant Pal
  • 706
  • 6
  • 19
  • Related: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – user0042 Nov 18 '17 at 09:43

1 Answers1

1

When you compile this, both SourceI.cpp and SourceII.cpp will have a copy of Object< int >. This is called code bloating and is one of the drawbacks with using templates.

When you link this, the linker will assume both instantiations of Object< int > are identical and throw away all but one.

super
  • 12,335
  • 2
  • 19
  • 29
  • 2
    So … there’s no drawback after all (in this case). – Konrad Rudolph Nov 18 '17 at 10:31
  • Does that mean the linker must know about C++ templates, after all? – Shukant Pal Nov 18 '17 at 12:17
  • Also, then pre-compiled headers come in use, right? – Shukant Pal Nov 18 '17 at 12:27
  • Yes, pre-compiled headers can reduce the compile-time overhead from the template being instantiated in different compilation units. – super Nov 18 '17 at 12:42
  • @SukantKumar — the linker doesn’t have to know about templates. In general, having two different things with the same name is an error; for some things it’s not, and the linker just picks one. Template instantiations fall in the latter class: duplicates are okay, so just pick one. – Pete Becker Nov 18 '17 at 13:58
  • @PeteBecker Clarification of your answer: This works for all type definitions. https://stackoverflow.com/a/33487918/6307827 – Andi May 11 '21 at 15:56
  • @Andi -- the linker doesn't know anything about types. It deals with names of code and data. – Pete Becker May 11 '21 at 16:07
  • @PeteBecker Can you explain me why the linker explains about `namespace myproj { int i; }` but does not about `namespace myproj { /*any class, struct, typedef, ...*/ }`, as soon as it is included into several object files? – Andi May 11 '21 at 16:27
  • 1
    @Andi — the first one generates data. The second one doesn’t. – Pete Becker May 11 '21 at 19:21