【发布时间】:2010-09-02 22:01:23
【问题描述】:
我正在编写一些使用 MSVC 在 Windows 上编译和链接(甚至发布了商业产品)的代码。虽然它不能用 GCC 编译,但我收到以下错误:
.../CBaseValue.h: In member function 'bool CBaseValue::InstanceOf()':
.../CBaseValue.h:90:18: error: invalid use of incomplete type 'struct CValueType'
.../CBaseValue.h:11:7: error: forward declaration of 'struct CValueType'
CBaseValue.h
class CValueType;
class CBaseValue {
public:
...
template <typename _Type>
bool InstanceOf() {
CValueType* pType = GetType();
if(pType == NULL) {
return false;
}
else {
return pType->IsDerivedFrom<_Type>();
}
}
...
}
CValueType.h
class CValueType : public CBaseValue {
public:
...
template <typename _Type>
bool IsDerivedFrom() {
return IsDerivedFrom(_Type::TYPEDATA);
}
...
}
我明白为什么这是个问题。基类 (CBaseValue) 有一个使用派生类(在本例中为 CValueType)的模板化函数。
看起来 MSVC 并没有完全遵守 C++ 规范,我只是被它咬了。但是,在调用模板函数的代码实际编译之前使用前向声明的 MSVC 行为现在也更可取。有谁知道一种解决方法,我可以让这个代码与 GCC 一起工作,而不必重写很多基本代码?
从我自己的研究看来,将“-fno-implicit-templates”传递给 g++ 会有所帮助,但我需要明确定义调用的模板类型。它们有很多,所以如果我能避免的话,我会更喜欢它。如果普遍认为这是我最好的选择……那就这样吧!
如果有人想知道,我将代码移植到 Mac 上,这就是我们现在使用 GCC 的原因。
【问题讨论】:
-
我怀疑模板是一个红鲱鱼。你能拿出模板并确认这仍然是一个问题吗?
-
CBaseValue::InstanceOf的定义不能在class CValueType的定义之后移动到CValueType.h中吗? -
不幸的是,我无法取出模板 - 它是整个类型系统(在我们的引擎中)所基于的模板化函数。出于这个原因,我也不能(不更改大量代码)将函数移出 CBaseValue 并移入 CValueType。
-
@tony:我的意思不是在你的生产代码中。我的意思是创建一个最小的可编译测试用例,然后尝试它。如果结果相同,那么您可以简化您的问题标题和代码 sn-p。
-
@tonythetiger:请参阅我的答案,了解我相信 Charles 所指的代码。它不是
CValueType的成员,它仍然是CBaseValue的成员,只是使用了外联定义(使用inline关键字保持内联优化语义)。
标签: c++ visual-c++ templates g++ forward-declaration