我想定义一个包含多个mutable
字段的聚合(将其保存在std::set
或std::priority_queue
中并在将来修改它,确保保存容器不变量)。我尝试了以下语法并成功编译:
#include <cstdlib>
int
main()
{
struct X
{
mutable struct
{
int i;
int j;
};
};
X const x{};
//x.i = 1;
return EXIT_SUCCESS;
}
但声明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;
}
也会出错:
错误:无法在const成员函数'f'
中分配给非静态数据成员注意:成员函数'main():: X :: f'在这里声明为const void f()const {i = 1; }
答案 0 :(得分:4)
麻烦来自于匿名E152: Cannot open /Users/Mikkel/.vim/bundle/nerdtree/doc/tags for writing
与struct
的非标准(在C ++中)使用的混合。后者是一个存储类说明符,用于成员而不是类型。
根据标准C ++的规则,您可以定义一个可变的成员:
mutable
您可以将结构中的成员定义为可变的。当匿名结构将这些成员合并到封闭结构中时,将传递mutable属性:
struct X
{
mutable struct
{
int i;
int j;
} y;
};
X const x{};
x.y.i = 1;
standatad C ++不允许使用匿名结构。匿名结构是compiler extension for C11 compatibility。
C ++标准允许匿名联盟。但它设定了限制,特别是:
9.5 / 6:类范围内的匿名联合声明中不允许存储类。
因此在编译以下代码时:
struct X
{
struct
{
mutable int i;
mutable int j;
};
};
编译器应该并将发出一个非常具体的错误:
struct X
{
mutable union
{
int i;
int j;
};
};
我认为允许在匿名结构上使用存储类说明符(并且显然忽略它)并为匿名联合发出错误并不一致。据我说,这将被报告为编译器错误。在任何情况下,您都应该采用备选方案1(便携式和兼容性)或备选方案2(依赖于编译器,但更符合标准)。