2

I have the following code:

template <typename T>
class A {
    public:
        static int a;
};

class B {
    public:
        static A<int> a1;
        static A<double> a2;
};

int B::a1::a = 0; --> It gives an error "a1 is not a class, namespace, enumeration"

(I am using llvm compiler in XCode. I can reproduce the problem with gcc as well.)

How can I Declare/define/initialize a static member variable of template classes as static member variables of a class?

syko
  • 3,477
  • 5
  • 28
  • 51

1 Answers1

4

Static members are defined base on their class. a is static member of A, a1 and a2 are static members of B, you can't mix up their definition.

Define them seprately:

template <typename T>
int A<T>::a = 0;

A<int> B::a1;
A<double> B::a2;

If you want template specialization for definition of A<T>::a, it will look like:

template <typename T>
int A<T>::a = 0;
template <typename T>
int A<int>::a = 1;
template <typename T>
int A<double>::a = 2;

Then for A<int>::a the initial value will be 1, for A<double>::a will be 2, for other types like A<char>::a it will be 0. Note the definitions is still independent of the definitions of class B.

If you want to access a from B::a1, you could write B::a1.a; since a1 is a A<int>, the result is same as A<int>::a.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • 2
    Further, you should define the template member `A::a` in the header, along with the rest or the template, and the (non-template) members of `B` in a source file. – Pete Becker Oct 18 '16 at 01:57
  • Isn't 'a' a static member variable for each of A and A, not one of A? (There is no class called 'A'. Only A and A I think?) – syko Oct 18 '16 at 01:58
  • @syko Yes, `A` has a static member `a`, and `A` has its own static `a`. The above definition will be used for these cases. So if you use `A`, `A::a` will be defined, if you use `A`, `A::a` will be defined... – songyuanyao Oct 18 '16 at 02:01
  • @songyuanyao thanks. then how can I access 'a' of a1 of B? 'B::a1::a' does not work neither for referencing. – syko Oct 18 '16 at 02:05
  • 1
    @syko It should be `B::a1.a`; Since `a1` is a `A`, the result is same as `A::a`. – songyuanyao Oct 18 '16 at 02:09