具有非平凡constexpr析构函数的约束函数重现对象

Tyk*_*ker 6 c++ language-lawyer c++20

如果一切顺利,C ++ 20将具有新的consteval关键字和constexpr析构函数。遗憾的是,我目前所知没有编译器实现约束。以下代码将有效。

struct A {
  constexpr ~A() {}
};

consteval A f() {
    return A{};
}

void test() {
    A a;
    a = f(); // <-- here
}
Run Code Online (Sandbox Code Playgroud)

问题来自我标记的行Af需要调用返回的临时对象的析构函数。但应在完整表达式的结尾处调用它。因此不在即时评估范围之内。

我没有从constevalconstexpr析构函数论文中找到任何明确禁止这样做的报价。但我看不出它怎么可能是正确的。

以下代码在C ++ 20中是否有效?此代码应如何处理?


注意:

当代论文中,给出了这个例子。在这里,consteval函数在常量上下文之外被调用。

consteval int sqr(int n) {
  return n*n;
}
constexpr int r = sqr(100);  // Okay.
int x = 100;
int r2 = sqr(x);  // Error: Call does not produce a constant.
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 3

我认为这段代码很好。

的显着方面consteval[expr.const]/12

如果表达式或转换可能被计算并且其最内部的非块作用域是立即函数的函数参数作用域,则该表达式或转换位于立即函数上下文中。如果表达式或转换是立即函数的显式或隐式调用并且不在立即函数上下文中,则它是立即调用。立即调用应是常量表达式。

void test() {
    A a;
    a = f(); // <-- here
}
Run Code Online (Sandbox Code Playgroud)

f()立即调用(它是不在立即函数上下文中的立即函数的显式调用)。所以要求是f()必须是一个常量表达式。

注意:只是f(), not a = f();,不要求这里的赋值运算符是常量表达式。

调用的一切都f()很好。的所有A特殊成员函数都可以在持续求值期间调用。的结果f()是常量表达式([expr.const]/10)的允许结果,同样因为它不会触发任何限制(A没有指针或引用成员,因此它们都没有引用没有 static 的对象储存期限)。

最终,持续评估的问题归结为检查所有限制列表并查看是否有任何问题。我认为我们没有违反任何规则,所以这应该没问题。

  • 临时的物质化及其随后的破坏不是立即调用的一部分。 (2认同)