编译器警告(等级 1)C5208 和错误 C7626

typedef 名称中使用的未命名的类不能声明非静态数据成员、成员枚举或成员类以外的成员

注解

typedef 声明中未命名的类除以下成员之外不能有其他任何成员:

  • 没有默认成员初始值设定项、
  • 成员类或
  • 成员枚举的非静态数据成员。

相同的限制以递归方式应用于每个嵌套类。 此限制旨在确保具有用于链接目的的 typedef 名称的结构的简单性。 它们必须足够简单,在编译器获取用于链接目的的 typedef 名称前,不需要进行任何链接计算。

此警告是 Visual Studio 2019 版本 16.6 中的新增功能。 根据 C++ 标准委员会采用的缺陷报告 P1766R1,它会影响编译器的所有标准模式。 在默认 /std:c++14/std:c++17 模式下,编译器针对非符合性代码抛出警告 C5208。 如果指定的是 /permissive-,编译器在 /std:c++14 下抛出警告 C5208 作为错误。 如果指定的是 /std:c++17 或更高版本,编译器针对非符合性代码抛出错误 C7626。

在不更改代码的情况下关闭警告

可以使用 warning 杂注 #pragma warning(suppress : 5208) 关闭特定代码行的警告。 还可以使用警告杂注 #pragma warning(disable : 5208) 关闭文件中的警告。 可以使用 /wd5208 命令行选项在命令行生成中全局关闭警告。

若要关闭 Visual Studio IDE 中整个项目的警告,请执行以下操作:

  1. 打开项目的“属性页”对话框。 有关如何使用“属性页”对话框的信息,请参阅属性页
  2. 选择“配置属性”>“C/C++”>“高级”页
  3. 编辑“禁用特定警告”属性以添加 5208。 选择“确定”以应用更改

示例

以下示例展示了未命名的结构中不再允许使用的构造。 将抛出 C5208 或 C7626 错误或警告,具体视指定的标准模式而定:

struct Base { };
typedef struct : Base // inheriting from 'Base'; ill-formed
{
    void fn(); // ill-formed
    static int i; // ill-formed
    struct U {
        void f(); // nested class has non-data member; ill-formed
    };
    int j = 10; // default member initializer; ill-formed
} S;

若要修复上面的代码,可以为未命名的类命名:

struct Base { };
typedef struct NamedType : Base
{
    void fn();
    static int i;
    struct U {
        void f();
    };
    int j = 10;
} S;