什么C ++ 14规则禁止constexpr函数对数据成员进行赋值? [英] What C++14 rule prohibits constexpr functions from making assignments to data members?
问题描述
我的理解是这个(无意义的)代码是无效的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 declarationconstexpr 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 markedconstexpr
, but note thatconstexpr
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屋!