gpt4 book ai didi

c++ - 为什么折叠表达式不能出现在常量表达式中?

转载 作者:IT老高 更新时间:2023-10-28 22:13:31 24 4
gpt4 key购买 nike

考虑以下代码:

template<int value>
constexpr int foo = value;

template<typename... Ts>
constexpr int sum(Ts... args) {
return foo<(args + ...)>;
}

int main() {
static_assert(sum(10, 1) == 11);
}

clang 4.0.1 给我以下错误:

main.cpp:6:17: error: non-type template argument is not a constant expression
return foo<(args + ...)>;
^~~~

这让我很惊讶。每个参数在编译时都是已知的,sum 被标记为 constexpr,所以我看不出为什么不能在编译时计算折叠表达式。

当然,这也会失败并显示相同的错误消息:

constexpr int result = (args + ...); // in sum

[expr.prim.fold]不是很有帮助,它很短,只描述了允许的语法。

尝试更新版本的 clang 也会得到相同的结果,gcc 也是如此。

他们是否真的被允许?

最佳答案

一个常量表达式可以包含一个折叠表达式。 不允许使用函数参数的值,除非函数调用本身是整个常量表达式的一部分。举例:

constexpr int foo(int x) {
// bar<x>(); // ill-formed
return x; // ok
}
constexpr int y = foo(42);

变量y需要用常量表达式初始化。 foo(42)是一个可接受的常量表达式,因为即使调用 foo(42)涉及对参数 x 执行左值到右值的转换。为了返回它的值,该参数在整个常量表达式foo(42)中创建。所以它的值是静态已知的。但是x本身不是foo 中的常量表达式.在它出现的上下文中不是常量表达式的表达式仍然可以是更大的常量表达式的一部分。

非类型模板形参的实参本身必须是常量表达式,但 x不是。所以注释掉的行格式不正确。

同样你的(args + ...)因为它对 sum 的参数执行左值到右值转换,所以它不是一个常量表达式(因此不能用作模板参数) .但是,如果函数 sum用常量表达式参数调用,函数调用作为一个整体可以是一个常量表达式,即使 (args + ...)出现在里面。

关于c++ - 为什么折叠表达式不能出现在常量表达式中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45430852/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com