Visual Studio 2010 不喜欢 mixin 中的 typedef typename

Visual Studio 2010 doesn't like typedef typename in mixin

本文关键字:中的 typedef typename mixin 不喜欢 Studio 2010 Visual      更新时间:2023-10-16

我有一些代码可以用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,但我想它就是这个库。如果是这样的话,文档显示Vector3dMatrix的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,因为您已经继承了它。