3

As far as I know, each template have different instances on each translation unit, and for my understanding a translation unit is roughly a cpp file.

So, if I have a file named test.hpp with the following contents:

// test.hpp
template <typename T> void test()
{
    static T t = T(0);
    return t++;
}

For each translation unit I should have a different instance of test even if the template parameter T is the same in each of them. I've decided to test it so I've created the following files (include guards are omitted for the sake of brevity):

// a.hpp
namespace A { void f(); }

// a.cpp
#include <iostream>
#include "a.hpp"
#include "test.hpp"
namespace A
{
void f() { std::cout << test<int>(); }
}

// b.hpp
namespace B { void f(); }

// b.cpp
#include <iostream>
#include "b.hpp"
#include "test.hpp"
namespace B
{
void f() { std::cout << test<int>(); }
}

As we can see, both a.cpp and b.cpp uses the int instance of the test() template but in different translation units, so executing the following program:

// main.cpp
#include "a.hpp"
#include "b.hpp"

int main()
{
    A::f();
    B::f();
    return 0;
}

I was expecting an output of 00 but i get 01 instead. The IDE I'm using to test this code is MSVC2010 V10.0.4 SP1.

So what's the question?

  • Is my understanding of the templates and translation units wrong? or...
  • I did something wrong with this test code?
PaperBirdMaster
  • 12,806
  • 9
  • 48
  • 94

1 Answers1

1

Is my understanding of the templates and translation units wrong?

Yes. It's wrong.
A copy of template function is created per type and not per translation unit.

In your case, for test<int> only 1 copy is created and same is used across all the TUs.

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • Would you mind to mention where in the standard is this characteristic mentioned? – PaperBirdMaster Mar 31 '15 at 11:37
  • @PaperBirdMaster See the question suggested as duplicate. – Suma Mar 31 '15 at 11:42
  • 1
    @Suma thanks: Standard 3.2/5 One Definition Rule. It can be readed [here](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf). – PaperBirdMaster Mar 31 '15 at 11:59
  • 1
    *A copy of template function is created **per type** and **not per translation unit*** It seems that it also happens with C++14 variable templates (see in[Wandbox](http://melpon.org/wandbox/permlink/HaGW0aa9marEpw19)), isn't it? – PaperBirdMaster May 04 '15 at 15:42
  • @PaperBirdMaster, yes that's correct. Since it's templated, anyway it will have only 1 copy. However if you specialize it, then again it will result in multiple definition error. e.g. `template T a = 1; template<> int a = 0;`, if you put this statement in a common header file then the 2nd statement will result in linker error. – iammilind May 05 '15 at 11:13