gpt4 book ai didi

c++ - 据我所知,下面的函数不是 constexpr,而是用 clang 和 g++ 编译的代码。我错过了什么?

转载 作者:可可西里 更新时间:2023-11-01 15:48:29 24 4
gpt4 key购买 nike

我从 N4140 的 §5.19/2 中得到这个例子:

constexpr int incr(int &n) {
return ++n;
}

据我所知,这不是一个 constexpr 函数。但是这段代码是用 clang 和 g++ 编译的。参见 live example .我在这里缺少什么?

最佳答案

在 C++14 中,constexpr 函数的规则放宽了,论文 N3597: Relaxing constraints on constexpr functions .该论文探讨了基本原理和效果,包括以下内容(强调我的):

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 用作核心常量表达式的子表达式,因此它不是病式的。

关于c++ - 据我所知,下面的函数不是 constexpr,而是用 clang 和 g++ 编译的代码。我错过了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34211688/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com