在C ++ 14中,由于constexpr
不再隐式const
,因此constexpr
成员函数可以修改类的数据成员:
struct myclass
{
int member;
constexpr myclass(int input): member(input) {}
constexpr void f() {member = 42;} // Is it allowed?
};
答案 0 :(得分:3)
据我所知,是的。限制来自[dcl.constexpr]:
constexpr
函数的定义应满足以下约束:
- 它不应是虚拟的(10.3);
- 其返回类型应为文字类型;
- 每个参数类型都应为文字类型;
- function-body 应为= delete
,= default
或复合语句,不包含
- asm-definition ,
goto
声明,- a try-block 或
- 非文字类型或静态或线程存储持续时间或其变量的定义 没有进行初始化。
该功能符合所有这些要求。
答案 1 :(得分:3)
是的,我相信此更改始于proposal N3598: constexpr member functions and implicit const,最终成为N3652: Relaxing constraints on constexpr functions的一部分,更改了部分7.1.5
段3
功能正文中允许的内容白名单:
它的函数体应为= delete,= default或a 仅包含
的复合语句
- null语句,
- static_assert-声明
- 未定义类或枚举的typedef声明和别名声明,
- 使用-声明
- using指令,
- 和一个return语句;
到黑名单:
其函数体应为= delete,= default或不包含
的复合语句
- asm-definition,
- goto声明,
- 试用版,或
- 非文字类型或静态或线程存储持续时间或其变量的定义 没有进行初始化。
并在第C.3.3
条第7款中添加了以下注释:声明:
更改:constexpr非静态成员函数不是隐式const 成员职能。
理由:必须允许constexpr成员函数改变 对象
对原始功能的影响:有效的C ++ 2011代码可能无法编译 本国际标准。例如,以下代码有效 在C ++ 2011中,但在本国际标准中无效,因为它 使用不同的返回类型声明相同的成员函数两次:
struct S { constexpr const int &f(); int &f(); };