Why static members of template classes are not unique

Take a look at the following code:

#include <iostream> template <typename T> class Foo { public: static T bar; }; template <typename T> typename T Foo<T>::bar; int main() { std::cout << "Foo<int>::bar : " << &Foo<int>::bar << std::endl; std::cout << "Foo<double>::bar : " << &Foo<double>::bar << std::endl; return 0; } 

This will print two different addresses. I can understand why in this case bar is of type T , and thus, instances of different T in Foo<T> will get different static members. However, if we change bar to a type that we already know (e.g. static int bar ), this still happens .

Why is this so? Why not just use bar for multiple instances of templates? How can I get only 1 bar object in all different instances?

+5
source share
3 answers

There is nothing surprising here.

 template <typename T> class Foo { //... }; 

Not a class, this is a template for stamping classes. This means that Foo<A> is a completely different class from Foo<B> . Thus, all static elements are unique to different instance instances; and the fact that the template template is the same has nothing to do with this context, since it is, after all, a template, a plan of class instances.

If you want all the different types of Foo share a common state, you can inherit them from the same base class and place the general information there. Here is an example:

 struct Foo_Base { static int bar; }; int Foo_Base::bar = 10; template<typename T> struct Foo : Foo_Base {}; int main() { Foo<int> foo_i; Foo<double> foo_d; std::cout << foo_i.bar << "\n"; foo_i.bar += 10; std::cout << foo_d.bar; } 

output:

 10 20 

Living example

+11
source

From the standard, $ 14.7 / 6 instance of the template and specialization [temp.spec]

Each specialized class template specification created from a template has its own copy of any static elements.

Foo<int> and Foo<double> are irrelevant classes, even if they are created from the same template and they will have their own static member bar , although their types are the same (for example, like int ).

+9
source

Foo<int>::bar and Foo<double>::bar are two different global (statically accessible classes) variables. they are not the same. Consider this code:

 template <typename T> class Foo { public: static T var1; static int var2; }; 

What do you think the relative layout of var2 be (suppose the compiler puts var2 right after var1 )? In one case, it can be relatively 1 byte ahead ( foo<char> ), but 8 bytes ahead in the case of a different data type.

0
source

All Articles