constexpr int incr(int &n) { return ++n; }
据我所知,这不是一个constexpr函数.但是这段代码在俚语和g中编译.见live example.我在这里缺少什么?
解决方法
As in C++11,the constexpr keyword is used to mark functions which the implementation is required to evaluate during translation,if they are used from a context where a constant expression is required. Any valid C++ code is permitted in constexpr functions,including the creation and modification of local variables,and almost all statements,with the restriction that it must be possible for a constexpr function to be used from within a constant expression. A constant expression may still have side-effects which are local to the evaluation and its result.
和:
A handful of syntactic restrictions on constexpr functions are
retained:
- asm-declarations are not permitted.
- try-blocks and function-try-blocks are not permitted.
- Declarations of variables with static and thread storage duration have some restrictions (see below).
我们可以在N4140第7.1.5节[dcl.constexpr]中找到这个内容:
The definition of a constexpr function shall satisfy the following constraints:
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.
最后一个例子显示了如何在constexpr中使用incr:
constexpr int h(int k) { int x = incr(k); // OK: incr(k) is not required to be a core // constant expression return x; } constexpr int y = h(1); // OK: initializes y with the value 2 // h(1) is a core constant expression because // the lifetime of k begins inside h(1)
而涵盖k的寿命的规则从h(1)开始就是:
- 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;
7.1.5 [dcl.constexpr]中的措词告诉我们为什么incr是一个有效的constexpr:
For a non-template,non-defaulted constexpr function or a non-template,non-defaulted,non-inheriting
constexpr constructor,if no argument values exist such that an invocation of the function or constructor
could be an evaluated subexpression of a core constant expression (5.19),the program is ill-formed; no
diagnostic required.
作为T.C的修改示例:
constexpr int& as_lvalue(int&& i){ return i; } constexpr int x = incr(as_lvalue(1)) ;
显示,我们确实可以使用incr作为核心常数表达式的子表达式,因此它不是不成形的.