在c++ 14中,constexpr成员可以更改数据成员

In C++14 can a constexpr member change a data member?

本文关键字:数据成员 成员 constexpr c++      更新时间:2023-10-16

在c++ 14中,由于constexpr不再隐式地是const, constexpr成员函数是否可以修改类的数据成员:

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

是的,我相信这个变化始于提案N3598: constexpr成员函数和隐式const,并最终成为N3652的一部分:放松对constexpr函数的约束,这改变了7.1.53中允许在函数体中的白名单:

它的函数体应该是= delete、= default或a只包含

的复合语句
  • 空语句,
  • static_assert-declarations
  • 类型定义声明和别名-不定义类或枚举的声明,
  • 通过声明,
  • using引用
  • 和一个返回语句;

到黑名单:

其函数体应为= delete、= default或不包含

的复合语句。
    一个asm-definition
  • ,
  • 一个尝试块,或者
  • 非文字类型或静态或线程存储持续时间的变量的定义

,并在C.3.3节第7条中增加了以下注释:

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

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

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

struct S {
 constexpr const int &f();
 int &f();
};

就我所知,是的。限制如下:from [dcl.constexpr]:

constexpr函数的定义应满足以下约束:
-它不应该是虚拟的(10.3);
-返回类型应为文字类型;
-它的每个参数类型都必须是文字类型;
-其函数体应为= delete= default或不包含

复合语句
  • asm-definition ,
  • a goto语句
  • a try-block
  • 非文字类型或静态或线程存储持续时间的变量的定义

函数满足所有这些要求。