为什么模板类的静态成员不是唯一的

时间:2016-05-20 11:47:27

标签: c++ templates c++14 static-members

看看以下代码:

#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;
}

这将打印出2个不同的地址。我理解为什么在这种情况下,bar属于T类型,因此Foo<T>中不同T的实例会为您提供不同的静态成员。但是,如果我们将bar更改为我们已知道的类型(例如static int bar)此still happens

为什么会这样?为什么不重复使用bar进行多个模板实例化?在不同的实例中,我怎么能只获得1 bar个对象?

3 个答案:

答案 0 :(得分:11)

这里没有什么令人惊讶的事情。

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

不是一个类,它是一个标记类的模板。这意味着Foo<A>Foo<B>完全不同。因此,所有静态成员对于不同的实例化类是唯一的 - 并且类模板相同的事实在此上下文中没有相关性,因为它毕竟是模板,实例化类的蓝图。

如果您希望所有不同类型的Foo共享一个公共状态,那么您可以让它们从同一个基类继承并将公共信息放在那里。这是一个非常简单的例子:

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;
}

输出:

10
20

Live Example

答案 1 :(得分:9)

从标准,$ 14.7 / 6模板实例化和专业化[temp.spec]

  

从模板实例化的每个类模板特化都有自己的任何静态成员副本。

Foo<double>bar是不相关的类,即使它们是从同一模板实例化的,并且它们将拥有自己的静态成员int,即使它们的类型是相同(例如public $file_ext_tolower = TRUE; }。

答案 2 :(得分:0)

Foo<int>::barFoo<double>::bar是两个不同的全局(静态可访问的类级别)变量。他们不一样。请考虑以下代码:

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

您认为var2的相对位置是什么(假设编译器在var2之后放置var1)?在一种情况下,它可能相对只提前1个字节(foo<char>),但在其他数据类型的情况下提前8个字节。