如何解决为什么 C++20 范围适配器的返回视图不是常量表达式?
考虑以下代码:
#include <ranges>
int main() {
constexpr int a[] = {1,2,3,4};
constexpr auto r = a | std::views::take(3);
static_assert(*r.begin() == 1);
}
msvc 接受它,gcc rejects 它与:
<source>:5:44: error: 'std::ranges::take_view<std::ranges::ref_view<const int [4]> >{3,std::ranges::ref_view<const int [4]>{(& a)}}' is not a constant expression
5 | constexpr auto r = a | std::views::take(3);
| ^
为什么 r
不是常量表达式?
解决方法
范围位是一个红鲱鱼。可以归结为这个
int main() {
constexpr int a[] = {1,2,3,4};
constexpr auto r = a ;
}
我们无法形成指向 constexpr
的第一个元素的 a
指针。这样的指针被限制为仅保存具有静态存储持续时间的对象的地址。视图对象(作为其实现的一部分)将需要保留一个迭代器(在我们的例子中是指针)的副本。
由于 r
被声明为 constexpr
并且它在内部持有一个指向对象的指针,因此该对象也必须具有静态存储持续时间。确实,修改代码以包含
static constexpr int a[] = {1,4};
让 GCC accept 成为您的榜样。
然而,MSVC 不符合标准。它也接受无效的普通指针示例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。