在C++中可以在堆上创建带有Consteval构造函数的类吗?

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

struct A {       
    consteval A() {}
};

int main() {
    new A{};
}

只有Clang才接受它。

GCC抱怨

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

和MSVC也是如此:

error C7595: 'A::A': call to immediate function is not a constant expression

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

哪个编译器在这里?


解决方案

哪个编译器在这里?

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


struct A { consteval A() {} };

consteval使A::A()成为立即函数1

立即函数只能从2,3

调用
  • 另一个即时函数,或
  • Constval If语句,或
  • 常量表达式4

new A{}不是上述各项。


1)[dcl.constexpr]/2

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

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

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

3)[expr.const]/13

如果表达式或转换可能被求值,并且: (13.1)其最内含非块作用域为立即函数的函数参数作用域,或
(13.2)它的封闭语句([stmt.pre])被constval if语句([stmt.if])的复合语句包围。

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

4)[expr.const]/11.2

常量表达式可以是指作为常量表达式(定义如下)的允许结果的实体的glValue核心常量表达式,也可以是其值满足以下约束的prValue核心常量表达式: (11.2)如果该值是指针类型,则它包含具有静态存储持续时间的对象的地址、超过该对象结尾的地址([Expr.Add])、非立即函数的地址或空指针值,

相关文章