将指针转换为范围

n. *_* m. 4 c++ c++20

这有效:

\n
const char* foo[] = {"This", "is", nullptr, "great"};\nfor (auto e : ::std::ranges::take_while_view (foo,             // <- array\n                    ([](const char* s){return s!=nullptr;})))\n      std::cout << e << "\\n";\n
Run Code Online (Sandbox Code Playgroud)\n

这不会:

\n
const char* foo[] = {"This", "is", nullptr, "great"};\nfor (auto e : ::std::ranges::take_while_view (&foo[0],         // <- pointer\n                    ([](const char* s){return s!=nullptr;})))\n      std::cout << e << "\\n";\n\nerror: no matching function for call to \xe2\x80\x98take_while_view(const char**,\n       main(int, char**)::<lambda(const char*)>)\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n

我们能否使用标准库类型和函数强制 C++ 将指针视为一种半无限范围,然后我们可以进一步限制它?

\n

我总是可以创建自己的类来表示半无限视图,但我宁愿在标准库中找到解决方案。

\n

Nic*_*las 5

有一种方法可以从不同的部分组装这样一个范围,但您不能隐式地将 a 视为T*一个整体。

您要做的就是subrange从指针构造 a ,用作unreachable_sentinel_t哨兵类型。所以你可以编写这样一个函数:

template<typename T>
auto inf_ptr_range(T *ptr)
{
  return std::ranges::subrange(ptr, std::unreachable_sentinel_t{});
}
Run Code Online (Sandbox Code Playgroud)

您可以在代码中使用它

const char* foo[] = {"This", "is", nullptr, "great"};
for (auto e : ::std::ranges::take_while_view (
        inf_ptr_range(foo),
        ([](const char* s){return s!=nullptr;})))
    std::cout << e << "\n";
Run Code Online (Sandbox Code Playgroud)

或者使用视图样式表示法:

int main()
{
const char* foo[] = {"This", "is", nullptr, "great"};
for (auto e : inf_ptr_range(foo) | std::views::take_while(
        [](const char* s){return s!=nullptr;}))
    std::cout << e << "\n";
}
Run Code Online (Sandbox Code Playgroud)