【问题标题】:How to print a range?如何打印范围?
【发布时间】:2025-11-28 13:05:02
【问题描述】:

我正在尝试使用范围比较 2 个数组并想打印它。

#include <algorithm>
#include <iostream>
#include <iterator>
#include <array>
#include <ranges>

int main()
{
  std::array<int, 9> test{0, 2, 3, 8, 0, 5, 4, 0, 1};
  std::array<int, 9> ref{1, 2, 3, 4, 5, 6, 7, 8, 9};

  //auto found = std::views::take_while([ ref, test ](auto *it) -> auto { it = std::ranges::find_first_of(ref, test); return it; });

  auto found1 = std::views::take_while([ref, test]() { return std::ranges::find_first_of(ref, test); });
  int *i{0};
  while (*i != std::ranges::end(found1)){
    std::cout << i << " ";
    i++;
  }
}

但编译失败,出现我不理解的错误

$ g++ main.cpp -std=c++20 -o main
main.cpp: In function ‘int main()’:
main.cpp:16:39: error: no match for call to ‘(const std::ranges::__cust_access::_End) (std::ranges::views::__adaptor::_RangeAdaptorClosure<std::ranges::views::__adaptor::_RangeAdaptor<_Callable>::operator()<{main()::<lambda()>}>::<lambda(_Range&&)> >&)’
   16 |   while (*i != std::ranges::end(found1)){
      |                                       ^

有没有办法打印 found1 ?

【问题讨论】:

  • 你试过 range-for 循环吗?即for (auto i : found1)?另外,如果它有效,你的代码究竟应该输出什么?
  • 您取消引用空指针*i{0}。即使它确实编译,该程序也会有未定义的行为。您的近端问题是尝试将结果 (UB) int 与 end/sentinel 迭代器进行比较。如果您解决了这个问题,由于取消引用空指针,您仍然会有 UB,并且 then 您将在不属于您的内存中递增,读取您从未构造或分配的值。不清楚你认为这会如何工作!

标签: c++ c++20 std-ranges


【解决方案1】:

你可以使用 fmt 库来输出范围,像这样:

    #include <algorithm>
    #include <iostream>
    #include <iterator>
    #include <array>
    #include <ranges>
    #include <fmt/format.h>
    #include <fmt/ranges.h>
    
    int main()
    {
      std::array<int, 9> test{0, 2, 3, 8, 0, 5, 4, 0, 1};
      auto v= test|std::ranges::views::take(5);
      fmt::print("{}\n",v);
}

【讨论】: