迭代包含在两个范围的交集中的对象

时间:2017-03-26 14:42:19

标签: c++ stl containers c++14 c++-standard-library

标准库中是否有某些东西允许我迭代包含在两个范围的交集中的对象?

特别是,给定一个函数对象action,我想获得一个等同于

的程序
/* some container supporting a push_back operation */ intersection;
std::set_intersection(first1, last1, first2, last2,
    std::back_inserter(intersection));
for (auto const& element : intersection)
    action(element);

无需插入intersection。当然,编写这样的代码很容易,例如

template<class InputIt1, class InputIt2, class UnaryFunction>
void for_each_in_intersection(InputIt1 first1, InputIt1 last1,
    InputIt2 first2, InputIt2 last2, UnaryFunction f)
{
    while (first1 != last1 && first2 != last2)
    {
        if (*first1 < *first2)
            ++first1;
        else
        {
            if (!(*first2 < *first1))
                f(*first1++);
            ++first2;
        }
    }
}

但我希望标准库中已有可用的内容。

2 个答案:

答案 0 :(得分:6)

您可以使用boost中的Function Output Iterator

#include <boost/function_output_iterator.hpp>
#include <vector>
#include <iostream>
#include <algorithm>

int main() {
    std::vector<int> v1 = {1, 2, 3, 4, 5};
    std::vector<int> v2 = {2, 4};
    std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),
            boost::make_function_output_iterator([](int i) {
                std::cout << i * i << '\n';
            }));
}

答案 1 :(得分:1)

我对STL一无所知,能以比你的代码更好的方式做你想做的事。

我能想到的更简单涉及std::for_each() std::find() std::binary_search()(谢谢,Rakete1111)和lambda函数。但我不认为这是一个好主意,因为不使用事实集合的订购搜索的值是有序的。

以下是一个完整的工作示例

#include <vector>
#include <iostream>
#include <algorithm>

template <typename T>
void action (T const & val)
 { std::cout << "- action over " << val << std::endl; }

int main()
 {
   std::vector<int> v1 { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
   std::vector<int> v2 { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };

   std::for_each(v1.cbegin(), v1.cend(),
                 [&](int val) {
      if ( std::binary_search(v2.cbegin(), v2.cend(), val) )
         action(val);
    });
 }