模板静态变量在类ctor中未定义

时间:2013-04-04 04:55:14

标签: c++ templates

我已经定义了下面的类层次结构,我的目的是设计一个允许我迭代枚举对象的泛型类(不幸的是不允许使用C ++ 11)。类定义和测试程序是:

// base.h

#include <set>

template <typename T>
class Base
{
protected:
   explicit Base(int value);
   typedef typename std::set< Base<T>* > instances;
   static instances s_instances;
   int value_;


public:
   int get_value() const { return value_ ; }
};

template <typename T>
Base<T>::Base(int value): value_(value)
{
   s_instances.insert(this);
}

// derived.h

#include "base.h"

class Derived : public Base<Derived>
{
protected:
    explicit Derived(int value): Base<Derived>(value) { }

public:
    static const Derived value1;
};

// test.cc

#include "derived.h"


template<>
Base<Derived>::instances Base<Derived>::s_instances;

const Derived Derived::value1(1);

int main(int argc, char *argv[])
{

   using std::cout;
   using std::endl;

   cout << Derived::value1.get_value() << endl;

}

在使用g ++(Ubuntu / Linaro 4.6.3-1ubuntu5)4.6.3进行编译时,它给出了以下链接错误: “

g++ test.cc -o test
/tmp/ccOdkcya.o: In function `Base<Derived>::Base(int)':
test.cc:(.text._ZN4BaseI7DerivedEC2Ei[_ZN4BaseI7DerivedEC5Ei]+0x28): undefined reference to `Base<Derived>::s_instances'
collect2: ld returned 1 exit status

任何人都可以在上面的代码中建议我缺少什么?

谢谢!

3 个答案:

答案 0 :(得分:1)

静态数据成员在类定义中声明,在类定义之外定义。像这样:

// header:
class C {
    static int i;
};

// source:
int C::i = 17;

使用模板,您通常不会在源文件中放置任何代码,因此定义在标题中:

// header:
template <class T>
class C {
    static int i;
};

template <class T>
int C<T>::i = 17;

答案 1 :(得分:0)

你只能写

// template<> -> you should not write this in this case.
Base<Derived>::instances Base<Derived>::s_instances;

如果您提供了Base<Derived>的明确专业化,例如:

class Derived;
template <>
class Base<Derived>
{
protected:
  explicit Base(int value);
  typedef typename std::set< Base<Derived>* > instances;
  static instances s_instances;
  int value_;


public:
  int get_value() const { return value_ ; }
};

否则,你必须坚持写作:

template<typename T>
typename Base<T>::instances Base<T>::s_instances;

答案 2 :(得分:0)

请注意,s_instances在使用之前可能尚未初始化。