我有一些代码可以用gcc编译得很好,但Visual Studio不喜欢。我把它提炼成下面的一个最小的例子:
#include "stdafx.h"
#include <Eigen/Dense>
template<class Base>
class Timestamp : public Base
{
public:
typedef typename Base::PointType PointType;
double timestamp;
};
/*
struct Point {};
struct PointXYZ : public Point
{
typedef PointXYZ PointType;
};
*/
struct PointXYZ : public Eigen::Vector3d
{
typedef PointXYZ PointType;
};
int _tmain(int argc, _TCHAR* argv[])
{
Timestamp<PointXYZ> point;
return 0;
}
错误为"error C2039: 'PointType' : is not a member of 'Eigen::PlainObjectBase<Derived>'"
类PlainObjectBase是Eigen库的一部分。如果我将PointXYZ的定义替换为注释中从空的"Point"类派生的定义,那么它在VS中也可以编译得很好。关于为什么会发生这种情况,以及VS可以像gcc那样接受它,有什么建议吗?
在Timestamp
中重新定义类型成员PointType
有什么原因吗?您已经从期望包含PointType
类型成员的类型继承,这意味着Timestamp
也通过继承具有PointType
类型成员。如果你从Timestamp
中去掉了这个typedef,你就不会有这个问题。
我不熟悉Eigen,但我想它就是这个库。如果是这样的话,文档显示Vector3d
是Matrix
的typedef(即Vector3d
只是Matrix
),其本身包含一个名为Base
的typedef,表示基类PlainObjectBase<Matrix>
:
typedef PlainObjectBase<Matrix> Base;
我的猜测是,当你这样做时:
typedef typename Base::PointType PointType;
Base
被评估为矩阵的Base
typedef,而不是模板类型参数Base
,因此它有效地尝试执行错误消息所说的操作:
typedef typename PlainObjectBase<Derived>::PointType PointType;
这显然失败了,因为PlainObjectBase
不包含PointType
类型的成员,更不用说这不是你想要做的
例如,将Timestamp
的模板类型参数更改为B
是否解决了问题?
template<class B>
class Timestamp : public B
{
public:
typedef typename B::PointType PointType;
double timestamp;
};
这将证实这就是问题所在,而且可能确实是VisualStudio2010中的一个错误(如果可以的话,请尝试更高版本)。不过就我个人而言,我建议简单地删除typedef,因为您已经继承了它。