我目前正在尝试用C ++编写一个类似Artemis的游戏组件/实体系统。我计划让这个系统使用跨平台工具在Android和iOS上编写名为MoSync的应用程序。
不幸的是,MoSync目前使用旧版本的GCC,当移植我在Visual Studio中测试的库时,我遇到了一大堆错误。我可以解决大部分问题,但是模板中有一个我无法理解的错误。
我写了一个小例子
template <typename T>
struct Base
{
static int type;
};
struct Derived : public Base<Derived>
{
};
template <typename T>
int Base<T>::type(-1);
extern "C" int MAMain()
{
Derived d;
d.type = 0;
}
我的库使用Curiously Recursive Template Pattern来定义组件。这个例子在GCC 4.4和Visual Studio 2010中编译得很好。但是当我尝试在MoSync(使用GCC 3.4.6)中编译它时,我得到了这个链接器错误
C:\MoSync\workspace\pede\main.cpp: Error: Unresolved symbol '__ZN4BaseI7DerivedE4typeE',
是否有解决方法可以在此编译器中使用它,或者我是否必须找到另一种方法来定义我的组件?
编辑* 事实上,我可以用一个更简单的例子来解决这个错误:
template <typename T>
struct Component {
static int t;
};
template <typename T>
int Component<T>::t(-1);
extern "C" int MAMain()
{
Component<int>::t = 0;
}
给出此错误
C:\MoSync\workspace\Components\main.cpp:9: Error: Unresolved symbol '__ZN9ComponentIiE1tE',
我想这可能与奇怪的递归模板模式没有任何关系。如何在GCC 3.4.6下编译呢?
答案 0 :(得分:1)
根据gcc bugtracker上的this bug report,问题是由静态变量定义中的默认值引起的。如果您删除初始化,代码应链接:
int Base<T>::type;
错误报告似乎已经解决,因为它不是一个错误。尽管如此,您的样本在GCC 4.4中编译良好。
要解决此问题,您可以使用带有构造函数的类类型,该构造函数将自动初始化。
答案 1 :(得分:0)
添加
int Base<Derived>::type(-1);
有帮助吗?
gcc 3.4真的开始变老了,并且没有与模板法术很好地合作。