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

Can a class with consteval constructor be created on heap in C++?

在下面的代码中 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

这里是哪个编译器?

Which compiler is right here?

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


struct A { consteval A() {} };

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

立即函数只能从2,3:

调用
  • 另一个立即函数,或者
  • consteval if 语句,或
  • 常量表达式4.

new A{}是上面的none。


1) [dcl.constexpr]/2

A constexpr or consteval specifier used in the declaration of a function declares that function to be a constexpr function. A function or constructor declared with the consteval specifier is called an immediate function.

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

A potentially-evaluated id-expression that denotes an immediate function shall appear only
(4.1) as a subexpression of an immediate invocation, or
(4.2) in an immediate function context.

3) [expr.const]/13

An expression or conversion is in an immediate function context if it is potentially evaluated and either:
(13.1) its innermost enclosing non-block scope is a function parameter scope of an immediate function, or
(13.2) its enclosing statement is enclosed ([stmt.pre]) by the compound-statement of a consteval if statement ([stmt.if]).

An expression or conversion is an immediate invocation if it is a potentially-evaluated explicit or implicit invocation of an immediate function and is not in an immediate function context.
An immediate invocation shall be a constant expression.

4) [expr.const]/11.2

A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints:
(11.2) if the value is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object ([expr.add]), the address of a non-immediate function, or a null pointer value,