繁体   English   中英

初始化模板化类的静态成员

[英]Initializing static members of a templated class

我试图弄清楚为什么这个例子不能编译。 我的理解是,如果没有显式设置静态变量,那么它默认为0.在下面的五个示例中,其中四个行为与我期望的一样,但是被注释掉的那个将不会编译。

#include <iostream>
class Foo
{
public:
    static int i;
    static int j;
};
template <int n>
class Bar
{
public:
    Bar(int) { }
    static int i;
}; 

static int i;
int Foo::i;
int Foo::j = 1;
template <> int Bar<2>::i;
template <> int Bar<3>::i = 3;

int main(int argc, char** argv)
{
    std::cout << "i         " << i << std::endl;
    std::cout << "Foo::i    " << Foo::i << std::endl;
    std::cout << "Foo::j    " << Foo::j << std::endl;
    //std::cout << "Bar<2>::i " << Bar<2>::i << std::endl; // Doesn't compile?
    std::cout << "Bar<3>::i " << Bar<3>::i << std::endl;
    return 0;
}

为什么不使用int Bar<2>::i做与int Foo::istatic int i相同的事情?

编辑:我忘了将模板<>添加到Bar <2>和Bar <3>声明中。 (虽然没有解决问题,仍然会收到链接器错误)

根据当前C ++标准的规则,专门化template <> int Bar<2>::i; 只是一个宣言而不是定义。 要成为定义,您必须指定初始化程序。 (见第14.7.3 / 15条)

除此之外,您缺少一个非常常见的情况:模板的非专用静态成员的定义:

template <int n> int Bar<n>::i;

这为Bar<N>::i提供了Bar<N>::i的定义,其中N不等于2或3。

根据标准C ++的最新草案,它说

14.7.3 / 13如果声明包含初始化器,则模板的静态数据成员的显式特化是一个定义; 否则,这是一个声明。
[注意:需要默认初始化的模板的静态数据成员的定义必须使用braced-init-list:

 template<> X Q<int>::x;       //declaration
 template<> X Q<int>::x ();    // error: declares a function
 template<> X Q<int>::x { };   // definition

- 结束说明]

如果您的编译器支持它,那么您所要求的是可能的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM