2017-03-26 69 views
3

標準庫中是否存在允許我遍歷包含在兩個範圍的交集中的對象的內容?迭代包含在兩個範圍的交集中的對象

特別地,給定的一個功能對象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; 
     } 
    } 
} 

但我希望標準庫中已經有一些東西可用。

+0

你只是想指針的容器來遍歷? – wally

+2

Range-v3,Boost.Iterator,Boost.Range等都具有此功能,但它不直接在stdlib中。 – ildjarn

+0

@Muscampester號只需看看[在cppreference.com上可能實現'std :: set_intersection]](http://en.cppreference.com/w/cpp/algorithm/set_intersection)。我想用'* d_first ++ = * first1 ++;'替換爲'action(* first1 ++);'替換相同的代碼。 – 0xbadf00d

回答

6

您可以使用Function Output Iterator從boost:

#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

很酷的東西!我建議使用[此鏈接](http://www.boost.org/doc/libs/release/libs/iterator/doc/function_output_iterator.html),它總是指向最新的增強版本。 – zett42

+0

@ zett42謝謝。 – Grisha

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); 
    }); 
} 
+0

您可以使用['std :: binary_search'](http://en.cppreference.com/w/cpp/algorithm/binary_search)而不是'std :: find',因爲容器是經過排序的,所以速度更快。 – Rakete1111

+0

@ Rakete1111 - 我沒有考慮過'std :: binary_search()';謝謝;所以真的更好 – max66