在 C++14 中,constexpr 成员可以更改数据成员吗?

Vin*_*ent 6 c++ constants member constexpr c++14

在 C++14 中,由于constexpr不再隐式constconstexpr成员函数可以修改类的数据成员:

struct myclass
{
    int member;
    constexpr myclass(int input): member(input) {}
    constexpr void f() {member = 42;} // Is it allowed?
};
Run Code Online (Sandbox Code Playgroud)

Sha*_*our 3

是的,我相信这一更改始于提案 N3598:constexpr 成员函数和隐式 const,并最终成为N3652:放宽对 constexpr 函数的约束的一部分,该更改更改了白名单中函数体中允许的部分7.1.5段落:3

其函数体应为=delete、=default或仅包含的复合语句

  • 空语句,
  • 静态断言声明
  • 不定义类或枚举的 typedef 声明和别名声明,
  • 使用声明,
  • 使用指令,
  • 以及一个返回语句;

到黑名单:

其函数体应为=delete、=default或不包含的复合语句

  • asm 定义,
  • 一个 goto 语句,
  • 一个 try 块,或者
  • 非文字类型或静态或线程存储持续时间的变量的定义,或者不执行初始化的变量的定义。

并在C.3.3第 7 条:声明中添加了以下注释:

更改:constexpr 非静态成员函数不是隐式 const 成员函数。

基本原理:需要允许 constexpr 成员函数改变对象。

对原始功能的影响:有效的 C++ 2011 代码可能无法在此国际标准中编译。例如,以下代码在 C++ 2011 中有效,但在此国际标准中无效,因为它两次声明相同的成员函数并具有不同的返回类型:

struct S {
 constexpr const int &f();
 int &f();
};
Run Code Online (Sandbox Code Playgroud)