gpt4 book ai didi

c++ - 在 istreambuf_iterator 中使用 C++20 范围

转载 作者:行者123 更新时间:2023-12-01 14:05:19 26 4
gpt4 key购买 nike

我无法编译(非常做作)C++ ranges example :

#include <ranges>
#include <fstream>
#include <vector>

template <typename R>
auto populate(R&& range)
{
return std::vector<char>(range.begin(), range.end());
}

int main(int argc, char* argv[]) {
auto stream = std::ifstream{"/etc/hosts"};

const auto is_odd = [](auto i) { return (i % 2) == 1; };
const auto hosts_data = populate(
std::ranges::subrange{std::istreambuf_iterator<char>{stream},
std::istreambuf_iterator<char>{}} |
std::views::filter(is_odd)
);

return EXIT_SUCCESS;
}

结果是:
<source>:19:35:   required from here
<source>:9:17: error: no matching function for call to 'std::vector<char>::vector(std::ranges::filter_view<std::ranges::subrange<std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ranges::subrange_kind::unsized>, main(int, char**)::<lambda(auto:13)> >::_Iterator, std::ranges::filter_view<std::ranges::subrange<std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ranges::subrange_kind::unsized>, main(int, char**)::<lambda(auto:13)> >::_Iterator)'

9 | return std::vector<char>(range.begin(), range.end());
|

从进一步的实验来看,似乎使用 istreambuf_iterator导致问题,但我不知道为什么。任何人都可以帮忙吗?

最佳答案

这让我很难过。
filter_view::iterator指定为,来自 [range.filter.iterator] :

constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int) requires forward_range<V>;

值得注意的是, subrangeistreambuf_iterator<char>不是 forward_range - 这是一个 input_range (因为 istreambuf_iterator 只是一个 input_iterator )。

因此,后缀 operator++返回 void而不是 iterator .

因此,我们特别的 filter_view::iterator不符合 cpp17-iterator的要求如 [iterator.traits]/2 中所述:
template<class I>
concept cpp17-iterator =
copyable<I> && requires(I i) {
{ *i } -> can-reference;
{ ++i } -> same_as<I&>;
{ *i++ } -> can-reference; // we fail this one
};

您试图在 vector 中调用的构造函数指定为,来自 [vector.overview] :
template<class InputIterator>
constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator());

这意味着,来自 [sequence.reqmts]/13 :

If the constructor

template<class InputIterator>
X(InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());

is called with a type InputIterator that does not qualify as an input iterator, then the constructor shall not participate in overload resolution.



并且我们的迭代器类型不符合输入迭代器的条件,因为后缀增量的结果不可解引用(另请参见 this table )。

至少这只是一个输入迭代器,因此无论如何都不会提高效率,因此您只需更改 populate() 的实现即可。至 if constexpr基于你是否真的从中得到了一个 cpp17 迭代器(基于检查 is_constructible)并且只是循环/ push_back除此以外。

出于某种原因 ranges::to from range-v3 不能在这里编译,但我认为这是一个编译器问题。

关于c++ - 在 istreambuf_iterator 中使用 C++20 范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62455297/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com