在boost::adaptors::filtered
过滤器功能的使用方式如下:
std::vector<int> input;
input += 1,2,3,4,5,6,7,8,9;
boost::copy(
input | filtered(is_even()),
std::ostream_iterator<int>(std::cout, ","));
在这种情况下管道运算符的作用是什么?它不是为 std::vector
定义的,它是重载吗?如果是这样,如何在 boost 等库中有效地搜索此类运算符?
最佳答案
这是一个 Boost Range Adaptor .此 online book "The Boost C++ Libraries" 中还编写了更多文档.
这样的范围有很多,可以组合起来写出高级的功能效果。例子在这里:
- Why is there no transform_if in the C++ standard library?
- Is it possible to use boost::filter_iterator for output?
filtered
适配器
input | filtered(is_even())
创建适配器类型的临时实例:
boost::range_detail::filtered_range<is_even, std::vector<int> >
这是一种对范围概念进行建模并保存对源范围 (input
) 的引用以及过滤谓词 (is_even()
) 的拷贝。
然后实现范围概念,使得范围的迭代产生双向范围,就好像它只有源范围中满足过滤谓词的元素一样。你同样可以这样写:
is_even predicate;
for (auto const& i : input)
if (predicate(i))
std::cout << i << ",";
range | adaptor
是生成新的适配 范围的表达式模板。
它如何/为什么与 |
一起工作?
真正的答案是“因为这就是它的设计和记录方式”。更技术性的解释是因为filtered(is_even())
类型为 boost::range_detail::filter_holder<is_even>
其中有一个重载 operator |
:
template< class SinglePassRange, class Predicate >
inline filtered_range<Predicate, SinglePassRange>
operator|(SinglePassRange& r,
const filter_holder<Predicate>& f)
{
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange>));
return filtered_range<Predicate, SinglePassRange>( f.val, r );
}
Note: The assert only verifies the minimum required traversal category. As documented you'll get "The minimum of the range category of rng and Bidirectional Range", which is a Bidirectional Range in this case (because vector has random traversal).
另一件事
I am already lost at input += 1,2,.... – user463035818 56 mins ago
那是 Boost Assign,与范围适配器无关,我敢打赌 C++11 使它在很大程度上已经过时了,因为你可以很容易地说
std::vector<int> input { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
或者确实
std::vector<int> input;
input.insert(input.end(), { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
关于c++ - c++ boost::adaptors::filtered 中管道运算符的作用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49658529/