模板化子类和模板化基类的静态成员特化

时间:2012-07-11 09:02:47

标签: c++ templates static specialization

我正在尝试从另一个模板化类(此处为A)继承模板化类(此处为C)并执行静态成员特化(此处为int var),但我无法获得正确的语法(如果这是可能的

#include <iostream>

template<typename derived>
class A
{
    public:
        static int var;
};

//This one works fine
class B
    :public A<B>
{
    public:
        B()
        {
            std::cout << var << std::endl;
        }
};
template<>
int A<B>::var = 9;

//This one doesn't works
template<typename type>
class C
    :public A<C<type> >
{
    public:
        C()
        {
            std::cout << var << std::endl;
        }
};
//template<>
template<typename type>
int A<C<type> >::var = 10;

int main()
{
    B b;
    C<int> c;
    return 0;
}

我放了一个与非模板化类(这里是B)一起工作的例子,我可以获得var的静态成员特化,但是对于C来说它不起作用。

这是gcc告诉我的:

test.cpp: In constructor ‘C<type>::C()’:
test.cpp:29:26: error: ‘var’ was not declared in this scope
test.cpp: At global scope:
test.cpp:34:18: error: template definition of non-template ‘int A<C<type> >::a’

我正在使用gcc 4.6.3版,感谢您的帮助

2 个答案:

答案 0 :(得分:0)

您可以通过编写var来提示编译器this->var是成员变量。

您无法编写模板来定义模板特化A<C<type>>的静态成员;当您定义静态成员时,您正在保留存储但是编写模板部分特化并不会告诉编译器为其保留存储的完全特化。你能做的最好就是写

template<>
int A<C<int> >::var = 10;

另一种方法是使用通过模板函数访问的函数级静态:

template<typename T> class A {
    static int &var() { static int var; return var; }
};

答案 1 :(得分:0)

我建议您在父类中使用枚举,并将子类中的值设置为父类的模板参数。对于C类'看'var,它可以是合格的。见下文:

#include <iostream>
using namespace std;

template<typename Child, int i = 0> // 0 is the default value
class A
{
    public:
        enum { var = i };
};

class B
    :public A<B>   // define the value or var here
{
    typedef A<B> Parent;
public:
    B()
    {
        cout << Parent::var << endl; // Parent:: here IS NOT necessary, just for uniformity's sake
    }
};

template<typename type>
class C
    :public A<C<type>, 200>  // define the value of var here
{
    typedef A<C<type>, 200> Parent;
public:
    C()
    {
        cout << Parent::var << endl; // Parent:: here IS necessary
    }
};


int main()
{
    cout << B::var << endl;
    cout << C<int>::var << endl;
    cout << C<char>::var << endl;
}