开发者

Initializing static members of a templated class

开发者 https://www.devze.com 2023-01-15 00:39 出处:网络
I\'m trying to figure out why this example doesn\'t compile. My understanding is that if a static variable is not expl开发者_运维问答icitly set then it defaults to 0. In the five examples below four o

I'm trying to figure out why this example doesn't compile. My understanding is that if a static variable is not expl开发者_运维问答icitly set then it defaults to 0. In the five examples below four of them behave as I would expect, but the one that's commented out won't compile.

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

Why doesn't int Bar<2>::i do the same thing as int Foo::i or static int i?

Edit: I had forgotten to add template<> to the Bar<2> and Bar<3> declarations. (doesn't solve the problem though, still getting linker errors)


Under the rules of the current C++ standard, the specialisation template <> int Bar<2>::i; is only a declaration and never a definition. To become a definition, you must specify an initialiser. (See clause 14.7.3/15)

Apart from that, you were missing one very common case: the definition of a non-specialised static member of a template:

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

This provides a definition for Bar<N>::i for N not equal to 2 or 3.


According to the latest draft of Standard C++ it says

14.7.3/13 An explicit specialization of a static data member of a template is a definition if the declaration includes an initializer; otherwise, it is a declaration.
[Note: the definition of a static data member of a template that requires default initialization must use a braced-init-list:

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

— end note ]

So what you are asking is possible, if your compiler is supporting it.

0

精彩评论

暂无评论...
验证码 换一张
取 消