1

I'm reading the book C++ primer 5th edition and I got this:

The fact that instantiations are generated when a template is used (§ 16.1.1, p. 656) means that the same instantiation may appear in multiple object files. When two or more separately compiled source files use the same template with the same template arguments, there is an instantiation of that template in each of those files.

I'm not sure if I got it correctly so I made an example here:

//test_tpl.h
template<typename T>
class Test_tpl
{
public:
    void func();
};

#include "test_tpl.cpp"


//test_tpl.cpp
template<typename T>
void Test_tpl<T>::func(){}


//a.cpp
#include "test_tpl.h"

// use class Test_tpl<int> here


//b.cpp
#include "test_tpl.h"

// use class Test_tpl<int> here

According to the paragraph above, in this example, Test_tpl is instantiated(Test_tpl<int>) twice. Now if we use explicit instantiation, Test_tpl<int> should be instantiated only once, but I don't know how to use this technique for this example.

Yves
  • 11,597
  • 17
  • 83
  • 180
  • 5
    `#include "test_tpl.cpp"`? – SergeyA May 18 '16 at 17:29
  • Where does the claim in your last sentence come from? – Kerrek SB May 18 '16 at 17:30
  • 1
    Also see: [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – NathanOliver May 18 '16 at 17:34
  • @SergeyA if not, we will get link error, right? – Yves May 18 '16 at 17:52
  • _@Thomas_ See @Nathan's link, that's not the right way to do it. – πάντα ῥεῖ May 18 '16 at 17:56
  • @NathanOliver thanks for your link but we could include cpp in the head file just like the accepted answer said, right? If not we have to define each instantiation for the template, is this really a good idea? what if we dont know all of the types of instantiations? – Yves May 18 '16 at 18:14
  • Normally one should never include a cpp file. If you want a separate implementation files the I suggest you use the way that is laid out in the accepted answer. – NathanOliver May 18 '16 at 18:26
  • @NathanOliver Yeah. I just read the link in that accepted answer. I should use the c++ key word `export` for this. – Yves May 18 '16 at 18:30

1 Answers1

1

You will have explicit instantiation with

//test_tpl.h

template<typename T>
class Test_tpl
{
public:
    void func();
};

//test_tpl.cpp

#include "test_tpl.h"

template<typename T>
void Test_tpl<T>::func(){} // in cpp, so only available here

template void Test_tpl<int>::func(); // Explicit instantiation here.
                                     // Available elsewhere.

//a.cpp #include "test_tpl.h"

// use class Test_tpl<int> here

//b.cpp #include "test_tpl.h"

// use class Test_tpl<int> here
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • If you don't include the CPP file in header, or don't implement all of template class in header, this process will only enable `` for `func` only, and would give linker errors. – Ajay May 18 '16 at 18:20
  • @Ajay Exactly. So it seems that explicit instantiation can limit the instantiations when users use the template. If we don't want to limit it, I think we have to include the CPP file in header. – Yves May 18 '16 at 18:27
  • @Thomas: Don't include cpp file, rename it for include as .inl, .hxx . – Jarod42 May 18 '16 at 19:30
  • @ you mean I just rename the file as `test_tpl.hxx`? May I know why? Is there any difference? – Yves May 18 '16 at 21:57
  • @Thomas: cpp files are files to compile, so even if *name.exe* would also "work", you should not use misleading extensions. – Jarod42 May 18 '16 at 23:10
  • @Jarod42 OK, got it. – Yves May 18 '16 at 23:35