2

假设我想从标准输入流中读取 n 个整数。阅读:

如何将 N 个整数读入向量?

我发现推荐的解决方案基本上是:

template<class InputIt, class Size, class OutputIt>
OutputIt copy_atmost_n(InputIt first, InputIt last, Size count, OutputIt result)
{
   for (Size i = 0; i < count && first != last; ++i)
      *result++ = *first++;
   return result;
}

auto read_n(std::istream& is, std::size_t n) {
    vector<int> result;
    // possibly reserve n elements
    copy_atmost_n(
       std::istream_iterator<int>(is),
       std::istream_iterator<int>(),
       n,
       std::back_inserter(result)
    );
    return result;
}

我不喜欢这个,原因如下:

  1. 的用途copy_atmost_n()是假设未能“取消引用”first迭代器将如何影响first的后续值。但这种假定的行为比普遍明显的更为特殊。我相信这会让很多开发人员感到困惑。
  2. 需要一个“暂存”变量。
  3. 的重复std::istream_iterator<int>

C++20,尤其是范围,是否为我们提供了更好的方法?

注意:返回一个std::vector<int>. 如果它使事情变得更容易,也可以使用某种惰性结构。

4

1 回答 1

3

答案应该†</sup> 是:

auto read_n(std::istream& is, std::size_t n) {
    return std::ranges::istream_view<int>(is) | std::views::take(n);
}

如果你只是想要一个懒惰的范围。然后急切地把它收集到vector<int>你认为合适的地方。


†</sup>但是由于LWG 3408 ,这还不太有效,但应该很快由P2259解决,所以它最终会是正确的。

于 2020-12-11T21:36:47.627 回答