什么C++ 14规则禁止constexpr函数为数据成员分配?

Kno*_*abe 5 c++ constexpr c++14

我的理解是这个(荒谬的)代码无效C++ 14:

class Point  {
public:
  constexpr double setX(double newX) { return x = newX; }
private:
  double x;
};
Run Code Online (Sandbox Code Playgroud)

我想弄清楚C++ 14标准中的哪一部分(仍然正式起草)不允许它.对constexpr功能的限制在7.1.5/2中列出.(抱歉格式错误.我无法弄清楚如何击败降价使其看起来正确.)

constexpr函数的定义应满足以下约束:

  • 它不应是虚拟的(10.3);
  • 其返回类型应为字面类型;
  • 每个参数类型都应是文字类型;
  • 它的函数体应为= delete,= default或不包含的复合语句
    • asm-definition,
    • 一个goto声明,
    • 尝试块,或
    • 非文字类型或静态或线程存储持续时间的变量的定义,或者不执行初始化的定义.

那里没有任何禁止分配给数据成员的东西.在5.19/2(子弹15)中有这样的禁令(再次出现格式错误,抱歉):

条件表达式e是核心常量表达式,除非根据抽象机器(1.9)的规则评估e将评估以下表达式之一:[...]对象的修改(5.17,5.2.6) ,5.3.2)除非它适用于文字类型的非易失性左值,指的是在e的评估范围内开始生命的非易失性对象;

但我不知道5.19如何适用于7.1.5.有人可以澄清一下吗?

Pot*_*ter 5

它是有效的 C++14。只要对象的生命周期包含在常量表达式的计算中,您就可以修改文字类类型的成员。

使用Point的常量表达式是有争议的(CWG DR 1452),但它是由当前的实现允许的。这将是一个文字类,除了它不是聚合(第 3.9.1/10 节),因为它有一个私有字段(第 8.5.1/1 节)。然而,它的构造不会调用它的非 constexpr 构造函数,因为它是可简单构造的。不管怎样,这个问题是通过添加声明来解决的constexpr Point() = default;

§5.19 限制了可以在常量表达式中计算的内容。一种限制是只能constexpr输入函数。§7.1.5 指定了哪些函数可以被标记constexpr,但请注意,constexpr函数可能包含(在条件语句中)不能在常量表达式中计算的东西。

参见提案文件、第二稿和第一稿。