什么C ++ 14规则禁止constexpr函数对数据成员进行赋值? [英] What C++14 rule prohibits constexpr functions from making assignments to data members?

查看:610
本文介绍了什么C ++ 14规则禁止constexpr函数对数据成员进行赋值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My understanding is that this (nonsensical) code is not valid C++14:

class Point  {
public:
  constexpr double setX(double newX) { return x = newX; }
private:
  double x;
};

我想知道(仍然正式起草)C ++ 14标准不允许它。对于constexpr函数的限制在7.1.5 / 2中列出。

I'm trying to figure out what part of the (still officially draft) C++14 Standard disallows it. The restrictions on constexpr functions are listed in 7.1.5/2. (Sorry for the mangled formatting. I can't figure out how to beat markdown into making it look right.)


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

The definition of a constexpr function shall satisfy the following constraints:


  • 它不应为虚拟(10.3);

  • 其返回类型应为文字类型;

  • 其每个参数类型都应为文字类型;

  • 应为= delete,= default或不包含

      的复合语句
    • 一个asm定义,

    • goto语句,

    • 一个try-block或

    • 定义非文字类型或静态或线程存储持续时间的变量,

    • it shall not be virtual (10.3);
    • its return type shall be a literal type;
    • each of its parameter types shall be a literal type;
    • its function-body shall be = delete, = default, or a compound-statement that does not contain
      • an asm-definition,
      • a goto statement,
      • a try-block, or
      • a definition of a variable of non-literal type or of static or thread storage duration or for which no initialization is performed.

      禁止分配给数据成员。在5.19 / 2(bullet 15)中有这样的禁止(再次带有格式化的对不起,对不起):

      There's nothing there that prohibits assignments to data members. There is such a prohibition in 5.19/2 (bullet 15) (again with mangled formatting, sorry):


      条件表达式e一个核心常量表达式,除非
      评估e遵循抽象机(1.9)的规则,
      将评估以下表达式之一:
      [...]
      修改一个对象(5.17,5.2.6,5.3.2),除非它被应用于字面类型的非易失性左值
      ,它指的是一个非易失性对象,其寿命在e的求值内开始; / p>

      A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions: [...] modification of an object (5.17, 5.2.6, 5.3.2) unless it is applied to a non-volatile lvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e;

      但我不知道5.19如何适用于7.1.5。有人能澄清吗?

      But I don't see how 5.19 applies to 7.1.5. Can somebody clarify?

      推荐答案

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

      It is valid C++14. You can modify members of a literal class type as long as the lifetime of the object is contained within the evaluation of the constant expression.

      使用 Point 在常量表达式中有争议( CWG DR 1452 ),但是它是当前实现允许的。它将是一个字面类,除了它不是聚合(§3.9.1/ 10),因为它有一个私有字段(§8.5.1/ 1)。但是它的构造不调用它的非constexpr构造函数,因为它是trivially构造的。无论如何,这个问题是通过添加一个声明 constexpr Point()= default; 修复。

      The use of Point in a constant expression is controversial (CWG DR 1452), but it is allowed by current implementations. It would be a literal class except that it is not aggregate (§3.9.1/10) because it has a private field (§8.5.1/1). However its construction does not invoke its non-constexpr constructor because it is trivially-constructible. Anyway, this issue is fixed by adding a declaration constexpr Point() = default;.

      §5.19限制可以在常数表达式中求值。一个限制是只能输入 constexpr 函数。 §7.1.5规定了什么函数可以被标记为 constexpr ,但是注意 constexpr 函数可以包含)无法在常量表达式中求值的事情。

      §5.19 restricts what can be evaluated in a constant expression. One restriction is that only constexpr functions may be entered. §7.1.5 specifies what functions may be marked constexpr, but note that constexpr functions may contain (in a conditional statement) things that cannot be evaluated in a constant expression.

      查看提案文件,第二第一草稿。

      See the proposal papers, second and first drafts.

      这篇关于什么C ++ 14规则禁止constexpr函数对数据成员进行赋值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆