我无法编译(非常人为的)C++ 范围示例:
#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;
}
Run Code Online (Sandbox Code Playgroud)
结果是:
<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());
|
Run Code Online (Sandbox Code Playgroud)
从进一步的实验来看,似乎是使用istreambuf_iterator导致了问题,但我不知道为什么。有人可以帮忙吗?
这让我很难过。
filter_view::iterator被指定为,来自[range.filter.iterator]:
constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int) requires forward_range<V>;
Run Code Online (Sandbox Code Playgroud)
值得注意的是, a subrangeofistreambuf_iterator<char>不是 a forward_range- 它是一个input_range(因为istreambuf_iterator只是一个input_iterator)。
因此,后缀 operator++返回void而不是iterator。
因此,我们的特殊性filter_view::iterator不满足[iterator.traits]/2中指定的要求:cpp17-iterator
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
};
Run Code Online (Sandbox Code Playgroud)
您尝试调用的构造函数vector被指定为,来自[vector.overview]:
template<class InputIterator>
constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
Run Code Online (Sandbox Code Playgroud)
这意味着,来自[sequence.reqmts]/13:
如果构造函数
Run Code Online (Sandbox Code Playgroud)template<class InputIterator> X(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());使用
InputIterator不符合输入迭代器资格的类型调用,则构造函数不应参与重载决策。
并且我们的迭代器类型不符合输入迭代器的资格,因为后缀增量的结果不可取消引用(另请参阅此表)。
至少这只是一个输入迭代器,所以无论如何都不会提高效率,因此您可以根据是否实际从中获得 cpp17-iterator (基于检查)来更改populate()to的实现(基于检查)并循环/否则。if constexpris_constructiblepush_back
由于某种原因ranges::to, range-v3 无法在这里编译,但我认为这是编译器问题。
| 归档时间: |
|
| 查看次数: |
390 次 |
| 最近记录: |