代码之家  ›  专栏  ›  技术社区  ›  char8_t

在成员函数的默认参数中使用强类型枚举的成员

  •  2
  • char8_t  · 技术社区  · 9 年前

    我主要使用C++,现在使用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中工作。

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

    2 回复  |  直到 9 年前
        1
  •  2
  •   bogdan    9 年前

    你的代码是有效的,VC14拒绝它是错误的。

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

    类被视为完全定义的对象类型(3.9)(或 完整型) } 类说明符 。在 班 构件规范 ,该类被视为在 函数体、默认参数、, 使用声明 介绍,介绍 继承构造函数(12.9), 异常规范 大括号或相等的初始值设定项 对于非静态数据成员(包括 嵌套类中的此类事物)。否则视为不完整 属于自己的班级 构件规范 .

    在默认参数中,查找 Bar::Baz 需要完整定义 Bar ,这在整个班级都有,所以一切都很好。

        2
  •  0
  •   Bizkit    9 年前

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