可变匿名结构

Mutable anonymous struct

本文关键字:结构      更新时间:2023-10-16

我想定义一个具有多个mutable字段的聚合(将其保存在std::setstd::priority_queue中,并在将来对其进行修改,当然会保存容器不变量)。我尝试了以下语法,并成功编译:

#include <cstdlib>
int
main()
{
    struct X
    {
        mutable struct 
        {
            int i;
            int j;            
        };
    };
    X const x{};
    //x.i = 1;
    return EXIT_SUCCESS;
}

clang 3.8的实例。

但是语句x.i = 1;给出了一个错误:

错误:无法为具有const限定类型"const x"的变量"x"赋值

我的意图是对大量的顺序文件进行分组,并将mutable关键字应用于该组。

这是语法错误吗?如果是这样的话,编译器制造商允许这样的语法(如果有的话)的意图是什么?

附加:

代码:

#include <cstdlib>
int
main()
{
    struct X
    {
        mutable struct 
        {
            int i;
            int j;            
        };
        void f() const { i = 1; }
    };
    X const x{};
    //x.i = 1;
    x.f();
    return EXIT_SUCCESS;
}

也给出了一个错误:

错误:无法分配给常量成员函数"f"中的非静态数据成员

注意:成员函数'main()::X::f'在此处声明为常量void f()const{i=1;}

问题来自匿名structmutable的非标准用法(在C++中)的混合。后者是一个存储类说明符,用于成员而非类型。

备选方案1:为匿名结构定义一个中间成员:

您可以根据标准C++的规则定义一个可变的成员:

struct X
{
    mutable struct 
    {
        int i;
        int j;            
    } y;
};
X const x{};
x.y.i = 1;

现场演示

备选方案2:使匿名结构中的每个成员都是可变的:

否则,您可以将结构中的成员定义为可变的。当匿名结构将这些成员合并到封闭结构中时,将传递可变属性:

struct X
{
    struct 
    {
        mutable int i;
        mutable int j;            
    };
};

在线演示

标准是怎么说的

标准C++不允许匿名结构。匿名结构是C11兼容性的编译器扩展。

然而,C++标准允许匿名联合。但它设置了限制,特别是:

9.5/6:在类作用域中的匿名并集声明中不允许使用存储类。

因此,在编译以下代码时:

  struct X
    {
        mutable union 
        {
            int i;
            int j;            
        };
    }; 

编译器将发布一个非常具体的错误:

prog.cpp:11:13: error: a storage class on an anonymous aggregate in class  scope is not allowed
         mutable union 

我认为,允许在匿名结构上使用存储类说明符(显然忽略了它)并为匿名联合发出错误是不一致的。根据我的说法,这将被报告为编译器错误。无论如何,您应该采用备选方案1(可移植和兼容)或备选方案2(依赖于编译器,但更符合标准)。