简体   繁体   English

为什么 C++20 范围适配器的返回视图不是常量表达式?

[英]Why the return view of C++20 range adaptors is not a constant expression?

Consider the following code:考虑以下代码:

#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 accept it, gcc rejects it with: msvc 接受它,gcc拒绝它:

<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);
      |                                            ^

Why does r is not a constant expression?为什么r不是常量表达式?

The ranges bit is a red herring.范围位是红鲱鱼。 It can be boiled down to this可以归结为这个

int main() {
  constexpr int a[] = {1, 2, 3, 4};
  constexpr auto r = a ;
}

We cannot form a constexpr pointer to the first element of a .我们不能形成一个指向 a 的第一个元素a constexpr指针。 Such pointers are constrained to hold only the addresses of objects with static storage duration.此类指针被限制为仅保存具有 static 存储持续时间的对象的地址。 The view object (as part of its implementation somewhere deep down) is going to need to keep a copy of an iterator (the pointer in our case).视图 object(作为其在深处实现的一部分)将需要保留迭代器的副本(在我们的例子中是指针)。

Since r is declared constexpr and it internally holds a pointer to an object, that object too must have static storage duration.由于r被声明为constexpr并且它内部包含一个指向 object 的指针,因此 object 也必须具有 ZA81259CEF456E95DC2974 存储持续时间。 Indeed, modifying the code to contain实际上,修改代码以包含

static constexpr int a[] = {1, 2, 3, 4};

Makes GCC accept your example happily.GCC 愉快地接受你的例子。

MSVC is non-conformant however.但是,MSVC 不符合要求。 It accepts the invalid plain pointer example as well.它也接受无效的普通指针示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM