且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

通用lambda及其作为常量表达式的参数

更新时间:2023-12-01 08:51:16

来自 expr.const] :

表达式e是核心常量表达式,除非按照抽象机的规则对e的求值将对以下表达式之一求值:

An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:

  • [...]
  • 从左值到右值的转换,除非将其应用于

  • [...]
  • an lvalue-to-rvalue conversion unless it is applied to

  • 整数或枚举类型的非易失性glvalue,它引用具有先前初始化,使用常量表达式初始化的完整非易失性const对象,或者
  • 一个非易失性glvalue,它引用字符串文字的子对象,或者
  • 非易失性glvalue,它引用用constexpr定义的非易失性对象,或引用这种对象的不可变异子对象,或者
  • 文字类型的非易失性glvalue,指的是其寿命在e的求值内开始的非易失性对象;
  • a non-volatile glvalue of integral or enumeration type that refers to a complete non-volatile const object with a preceding initialization, initialized with a constant expression, or
  • a non-volatile glvalue that refers to a subobject of a string literal, or
  • a non-volatile glvalue that refers to a non-volatile object defined with constexpr, or that refers to a non-mutable subobject of such an object, or
  • a non-volatile glvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e;

[...]

f(x)中,我们在x上执行从左值到右值的转换. x不是整数或枚举类型,它不是字符串字面量的子对象,也不是用constexpr定义的对象,并且它的生命周期不是从f(x)的评估开始的.

In f(x), we do an lvalue-to-rvalue conversion on x. x isn't of integral or enumeration type, it's not a subobject of a string-literal, it's not an object defined with constexpr, and its lifetime did not begin with the evaluation of f(x).

这似乎使它不是核心常量表达式.

That seems to make this not a core constant expression.

,由于S为空,因此其隐式生成的副本构造函数中的任何内容实际上都不会触发此左值到右值转换.这意味着该表达式中的任何内容实际上都没有违反任何核心常量表达式限制,因此gcc和clang在接受它方面是正确的.这种解释对我来说似乎是正确的. constexpr很有趣.

However, as Casey points out, since S is empty, nothing in its implicitly-generated copy constructor would actually trigger this lvalue-to-rvalue conversion. That would mean that nothing in this expression actually violates any of the core constant expression restrictions, and hence gcc and clang are correct in accepting it. This interpretation seems correct to me. constexpr is fun.