可以在 C++ 堆上创建具有 consteval 构造函数的类吗?

Fed*_*dor 11 c++ new-operator language-lawyer consteval

在下面的代码中,struct A有立即函数默认构造函数,并在动态内存中创建该结构的对象new A{}

struct A {       
    consteval A() {}
};

int main() {
    new A{};
}
Run Code Online (Sandbox Code Playgroud)

只有 Clang 接受。

海湾合作委员会抱怨

error: the value of '<anonymous>' is not usable in a constant expression
    6 |     new A{};
      |           ^
note: '<anonymous>' was not declared 'constexpr'
Run Code Online (Sandbox Code Playgroud)

MSVC 也这样做:

error C7595: 'A::A': call to immediate function is not a constant expression
Run Code Online (Sandbox Code Playgroud)

演示: https: //gcc.godbolt.org/z/6Px5WYGzd

这里是哪个编译器?

YSC*_*YSC 8

这里是哪个编译器?

使用 调用consteval构造函数的格式new不正确。
MSVC 和 GCC 拒绝它是正确的;clang 是错误的,因为需要诊断。


struct A { consteval A() {} };
Run Code Online (Sandbox Code Playgroud)

consteval生成立即A::A()函数1

立即函数只能从2,3调用:

  • 另一个立即函数,或者
  • 保守的 if 语句,或者
  • 常量表达式4 .

new A{}以上都不是。


1) [dcl.constexpr]/2

函数声明中使用的 or 说明符将该函数声明为 constexpr函数constexprconsteval用说明符声明的函数或构造函数consteval称为立即函数

2) [expr.prim.id.general]/4

表示立即函数的潜在求值 id 表达式只能
(4.1) 作为立即调用的子表达式出现,或
(4.2) 在立即函数上下文中。

3) [expr.const]/13

如果表达式或转换可能被求值并且满足以下任一条件,则该表达式或转换位于
立即函数上下文中: (13.1) 其最内层封闭非块作用域是立即函数的函数参数作用域,或者
(13.2) 其封闭语句被封闭 ([stmt .pre]) 由 consteval if 语句 ([stmt.if]) 的复合语句组成。

如果表达式或转换是立即函数的潜在评估显式或隐式调用并且不在立即函数上下文中,则它是立即调用。
立即调用应是常量表达式。

4) [expr.const]/11.2

常量表达式可以是泛左值核心常量表达式,它引用作为常量表达式(如下定义)允许的结果的实体,也可以是纯右值核心常量表达式,其值满足以下约束: (
11.2) 如果值为指针类型,它包含具有静态存储持续时间的对象的地址、超出此类对象末尾的地址([expr.add])、非立即函数的地址或空指针值,