GCC 3.4 中奇怪的递归模板模式(确切地说是 MoSync)

Curiously Recursive Template Pattern in GCC 3.4 (MoSync to be exact)

本文关键字:MoSync 模式 递归 GCC      更新时间:2023-10-16

我目前正在尝试用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;
} 

我的库使用奇怪的递归模板模式来定义组件。此示例在 GCC 4.4 和 Visual Studio 2010 中编译良好。但是当我尝试在MoSync(使用GCC 3.4.6)中编译它时,我收到此链接器错误

C:MoSyncworkspacepedemain.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:MoSyncworkspaceComponentsmain.cpp:9: Error: Unresolved symbol '__ZN9ComponentIiE1tE', 

我想这可能与奇怪的递归模板模式没有任何关系。我该怎么做才能在 GCC 3.4.6 下编译它?

根据 gcc 错误跟踪器上的这个错误报告,问题是由在静态变量定义中指定默认值引起的。如果按如下方式删除初始化,则代码应链接:

int Base<T>::type;
错误

报告似乎已解决为不是错误。尽管如此,您的示例在 GCC 4.4 中编译良好。

若要解决此问题,可以将类类型与将自动初始化自身的构造函数一起使用。

添加

int Base<Derived>::type(-1);

帮助?

GCC 3.4 真的开始过时了,不能很好地应对模板巫术。