VS 2013 - IntelliSense报告误报?

时间:2014-08-18 00:15:20

标签: c++ visual-studio intellisense

我正在开发一个C ++项目,除此之外,我还有一些带有一些纯虚方法的接口。当我尝试实现该接口时出现问题 - IntelliSense似乎不同意派生类的方法声明。这种方法的一个例子:

// DLL_EXPORT -> #define DLL_EXPORT __declspec(dllexport)
// IPlayer
DLL_EXPORT virtual const Grid& GetGrid() const = 0;

其中一个派生类中的声明:

// Human : IPlayer
DLL_EXPORT const Grid& IPlayer::GetGrid() const;

它一直唠叨我的错误 - “IntelliSense:声明必须对应于指定基类中的纯虚拟成员函数”。代码编译没有错误并运行正常,所有“有问题”的方法在运行时按预期执行其工作。值得一提的是,如果我在派生类中删除了IPlayer :: scope限定符,则错误消失。出于可读性原因,我想保留它。另外,我并不精通C ++,所以我提供的例子可能会出现明显错误。

1 个答案:

答案 0 :(得分:1)

最小化的例子:

struct C { virtual void f() = 0; };

struct D : C { void C::f() { } };

这不能在我测试的任何版本的g ++或clang中编译。 VS2013中的Intellisense使用EDG前端,并quote Jonathan Wakely,“如果GCC,Clang和EDG都同意,MSVC不同意这通常意味着MSVC是错误的。”

为了使事情变得更有趣,标准中的相关段落实际上在C ++ 11和C ++ 14之间发生了变化。

在C ++ 11中,这是完全违法的(N3337§8.3[dcl.meaning] / p1):

  

除了a的定义外, declarator-id 不具备资格   成员函数(9.3)或其外部的静态数据成员(9.4)   class,函数的定义或显式实例化   命名空间之外的命名空间的变量成员,或者   在其命名空间之外定义显式特化,或   友元函数的声明是另一个类的成员   或命名空间(11.3)。

由于CWG issue 482,此句在C ++ 14中被删除。该问题的拟议决议如下:

  

[起草说明:这里省略了“同类之外”没有   允许重新申请集体成员;那仍然是   9.2 [class.mem]第1段禁止的。删除   枚举可以使用qualified-id的声明类型   似乎允许typedef声明使用qualified-id,即   以前是不允许的;如果这是不受欢迎的,禁令可以   在这里恢复。]

在C ++ 14中,§8.3[dcl.meaning] / p1中唯一适用的规则现在是(引用N3936):

  

declarator-id 合格时,声明应引用a   以前声明的类或名称空间的成员   限定符指的是(或者,在命名空间的情况下,指的是元素的元素)   该命名空间的内联命名空间集(7.3.1))或特化   物;该成员不仅仅是由一个人介绍的    using-declaration 在由类提名的类或命名空间的范围内    declarator-id 嵌套名称说明符

§9.2[class.mem] / p1的相关部分是:

  

除非用于宣布朋友(11.3)或引入其名称   基类的成员到派生类(7.3.3),    member-declarations 声明该类的成员,以及每个成员    member-declaration 应声明至少一个成员名称   类。会员不得两次申报    member-specification ,但嵌套类或成员类除外   模板可以声明然后定义,除了一个   枚举可以通过 opaque-enum-declaration 引入   后来用枚举说明符重新声明。

由于 using-declaration “将基类的成员引入派生类”是一个显式异常,因此基类成员似乎不被认为是成员的目的。规则“ member-declarations 声明该类的成员,并且每个此类 member-declaration 应声明该类的至少一个成员名称”。如果是这样,那么在C ++ 14中也不允许在成员声明中使用 qualified-id ,如void C::f() { },因为< em> qualified-id 是指C的成员,而不是D的成员。