Why are static members of template classes not unique

倖福魔咒の 提交于 2019-12-23 12:18:54

问题


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 out 2 different addresses. I can understand why in this case, bar is of type T and thus instantiations of different T's in Foo<T> will get you different static members. However, if we change bar to a type we already know ( e.g. static int bar ) this still happens.

Why is this the case? Why just not re-use bar for multiple template instantiations? How would I be able to get just 1 bar object throughout different instantiations?


回答1:


There is nothing really surprising going on here.

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

Is not a class, it is a template to stamp out classes. That means Foo<A> is a completely different class from Foo<B>. As such all static members are unique to the different instantiated classes — and the fact that class template being same has no relevance in this context, as it is after all a template, the blueprint of the instantiated classes.

If you want all the different kinds of Foo's to share a common state then you can have them inherit from the same base class and put the common information there. Here is a very boiled down 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

Live Example




回答2:


From the standard, $14.7/6 Template instantiation and specialization [temp.spec]

Each class template specialization instantiated from a template has its own copy of any static members.

Foo<int> and Foo<double> are irrelevant classes, even though they're instantiated from the same template, and they will have their own static member bar, even though their types are same (e.g. both int).




回答3:


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

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

What do you think the relative placement of var2 be (assume compiler places var2 just after var1)? In one case, it may be relatively just 1 byte ahead (foo<char>), but 8 bytes ahead in case of other datatype.



来源:https://stackoverflow.com/questions/37345946/why-are-static-members-of-template-classes-not-unique

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!