为什么 const 视图不是范围?

Tob*_*ght 5 c++ c++20 std-ranges

如果我创建一个视图,那么它就是一个范围。这似乎很合理。

\n

但是,如果它是 const,那么它就变成非范围:

\n
#include <ranges>\n\nint main()\n{\n    int values[] = { 1, 2, 3 };\n\n    auto odd_values = values | std::views::filter([](int i){ return i % 2; });\n    static_assert(std::ranges::range<decltype(odd_values)>);\n\n    auto const odd_ref = odd_values;    \n    static_assert(!std::ranges::range<decltype(odd_ref)>); // WHY NOT?\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是令人惊讶的 - 我看不出有任何理由我不应该能够阅读内容,就像我可以从const std::vector.

\n

如果这是一个实现错误,我在 GCC 11 中遇到过这种情况,使用-std=c++20; 库是 libstdc++-11。

\n
\n

如果我添加一个调用,std::ranges::begin()我会得到大量诊断信息,显示它没有找到成员函数,也没有通过 ADL 找到任何内容,然后遇到了阻止std::begin匹配的后备删除函数。

\n

从错误消息来看,我们似乎缺少视图类中的const 版本begin()和成员函数。end()这是预期的结果,还是只是被错过了?

\n

这让我想到了一个更简单的失败示例:

\n
#include <ranges>\n\nint main()\n{\n    int values[] = { 1, 2, 3 };\n\n    auto const odd_values = values | std::views::filter([](int i){ return i % 2; });\n\n    odd_values.begin();  // ERROR HERE\n}\n
Run Code Online (Sandbox Code Playgroud)\n
#include <ranges>\n\nint main()\n{\n    int values[] = { 1, 2, 3 };\n\n    auto odd_values = values | std::views::filter([](int i){ return i % 2; });\n    static_assert(std::ranges::range<decltype(odd_values)>);\n\n    auto const odd_ref = odd_values;    \n    static_assert(!std::ranges::range<decltype(odd_ref)>); // WHY NOT?\n}\n
Run Code Online (Sandbox Code Playgroud)\n

那么为什么视图没有 const 版本的begin()end()呢?

\n