c++ - consteval 函数返回具有非平凡 constexpr 析构函数的对象
问题描述
如果一切顺利, C++20 将拥有新的consteval关键字和constexpr 析构函数。遗憾的是,我所知道的编译器目前没有实现consteval。以下代码有效吗?
struct A {
constexpr ~A() {}
};
consteval A f() {
return A{};
}
void test() {
A a;
a = f(); // <-- here
}
问题来自我标记的行——需要调用临时A
返回的析构函数。f
但它应该在完整表达式的末尾调用。所以在即时评价之外。
我没有从consteval和constexpr 析构函数论文中找到任何明确禁止这样做的引用,但我看不出它怎么可能是正确的。
以下代码在 C++20 中有效吗?这段代码应该发生什么?
笔记:
在consteval 论文中,给出了这个例子。这里 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.
解决方案
我认为这段代码很好。
的突出方面consteval
是[expr.const]/12:
如果表达式或转换可能被评估并且其最内部的非块范围是立即函数的函数参数范围,则表达式或转换位于立即函数上下文中。如果表达式或转换是立即函数的显式或隐式调用并且不在立即函数上下文中,则它是立即调用。立即调用应为常量表达式。
在
void test() {
A a;
a = f(); // <-- here
}
f()
是立即调用(它是对不在立即函数上下文中的立即函数的显式调用)。所以要求是f()
必须是一个常量表达式。
注意: just f()
, not a = f();
,这里的赋值运算符不要求是常量表达式。
调用的一切都f()
很好。的所有A
特殊成员函数都可以在恒定评估时间内调用。的结果f()
是常量表达式([expr.const]/10)的允许结果,同样因为它也不会触发那里的任何限制(A
没有指针或引用成员,所以它们都没有引用没有静态的对象存储时间)。
最终,不断评估的问题归结为检查所有限制列表并查看是否有任何问题。我认为我们没有违反任何规则,所以这应该没问题。
推荐阅读
- button - 我需要帮助更改按钮的大小
- javascript - 如何使用 PHP 安全地为 JavaScript 准备字符串?
- r - 火山图错误............“FUN 中的错误(X [[i]],......):找不到对象'Qval'”
- php - 搜索数据库后在电子表格中生成边框时出现致命错误
- sql - 将微秒添加到时间戳并分配给 DB2 中的主机变量 - BIND ERROR FROM BUILD
- typescript - 在另一个属性的断言之后的一个属性的打字稿推断
- excel - VBA 宏代码将多个图表从 Excel 复制到 Words 并将它们保存在不同的文档中
- r - 在 R 中使用 lapply 循环遍历 R 中的 data.frames 列表
- html - 标签在 div 内不可点击
- reactjs - 无法读取 undefined 的属性“事务”。反应原生