2

我主要使用 G++,现在使用 Visual Studio 2015。我想用 VC++2015 构建我的项目,但我收到错误消息,指出在给定默认参数的函数中无效使用 '::' 并带有前向声明的强类型枚举。

这是一些代码:

struct Foo
{
    //! Forward declaration of Bar
    enum class Bar : short;

    //! "Faulty" function with default argument
    void DoSmth(Bar aBar = Bar::Baz)
    {
        // ... code ...
    }

    //! Complete declaration of Bar
    enum class Bar : short
    {
        Baz
    };
};

int main() { }

在使用默认参数 Bar::Baz 声明函数 DoSmth() 时,它给了我以下错误:

test.cpp(7): error C2589: '::': illegal token on right side of '::'
test.cpp(7): error C2059: syntax error: '::'
test.cpp(17): fatal error C1903: unable to recover from previous error(s); stopping compilation

使用 G++(使用 4.9 和 5.1 测试)代码编译得很好,但使用 VC++2015 则不行。

我完全知道我必须在使用前声明一些东西,但是。仅仅是因为 VC++2015 没有在类的范围内寻找 Bar 的完整声明和定义,而 G++ 却可以吗?或者,也许 G++ 只是采用完整的声明并将其与前向声明“合并”(因为它们在同一范围内),从而使其对类完全可用?或者也许我完全错了,完全不同的东西导致了这个?

我可以忍受我必须更改所有强类型枚举的声明才能使其与 VC++2015 一起使用。

但我也想知道这是为什么?

4

2 回答 2

2

您的代码是有效的,VC 14 拒绝它是错误的。

根据N4527,当前的标准工作草案,[9.2p2]:

}class-specifier结束时,类被视为完全定义的对象类型 (3.9)(或完整类型)。在类成员规范中,类在函数体、默认参数、引入继承构造函数的使用声明(12.9)、异常规范和 非静态数据成员的大括号或等式初始化器(包括嵌套类中的此类内容)。否则,它在其自己的类成员规范中被视为不完整。

在默认参数中,查找Bar::Baz需要 的完整定义Bar,该定义在完整的类中可用,所以一切都很好。

于 2015-08-04T13:04:10.203 回答
0

也许现在的解决方法是将enum class函数调用之前的完整定义移动到DoSmith().

于 2015-08-04T13:51:12.763 回答