2013-04-26 1 views
1

У меня есть два массива следующим образом:Iterable объединение двух векторов

std::array<int,6> A,B; 
//Fill A with random data 
//File B with random data 

По какой-то причине, я хотел бы какой-то объект-контейнер, который позволяет мне получить доступ к обоим векторам индивидуально, но и перебирать над их объединения, что позволяет такие действия, как следует:

union_container uc(A,B); 
for(unioned::iterator i=uc.begin();i!=uc.end();++i) 
    *i+=1; 
uc.first()[2]=4; 
uc.second()[4]=5; 

Я мог бы код этот unioned класс сам, но, возможно, уже есть библиотека, которая позволяет это?

+0

Возможно [boost :: zip_iterator] (http://www.boost.org/doc/libs/1_53_0/libs/iterator/doc/zip_iterator.html)? – yhager

+0

Я бы хотел попробовать, @yhager, но как вы предлагаете его использовать? – Richard

+0

помог ли мой ответ? если нет, пожалуйста, помогите мне улучшить его. – TemplateRex

ответ

1

Использование Boost zip iterators является одним из способов сделать это.

#include <array> 
#include <functional> 
#include <iostream> 
#include <boost/tuple/tuple.hpp> 
#include <boost/iterator/zip_iterator.hpp> 

template<typename T> 
using ZipIt = boost::zip_iterator< boost::tuple<T*, T*> >; 

template<typename T> 
using ZipRef = decltype(*ZipIt<T>()); 

template<typename T> 
void operator+=(ZipRef<T> z, T const& v) 
{ 
    z.template get<0>() += v; 
    z.template get<1>() += v;  
} 

int main() 
{ 
    std::array<int, 6> a = { 1, 3, 5, 7, 9, 11 }; 
    std::array<int, 6> b = { 2, 4, 6, 8, 10, 12 }; 

    std::for_each(
     boost::make_zip_iterator(boost::make_tuple(std::begin(a), std::begin(b))), 
     boost::make_zip_iterator(boost::make_tuple(std::end(a), std::end(b))), 
     [](ZipRef<int> z){ z += 1; } 
    ); 

    std::copy(std::begin(a), std::end(a), std::ostream_iterator<int>(std::cout, ",")); std::cout << "\n"; 
    std::copy(std::begin(b), std::end(b), std::ostream_iterator<int>(std::cout, ",")); std::cout << "\n"; 

    a[2] = 4; 
    b[4] = 5; 
} 

output.

Обратите внимание, что приведенный выше код не такой общий, как мне бы хотелось, так как переход к вариативным шаблонам и общим типам итераторов оказался немного волосатым (левым упражнением!) Это в основном связано с тем, что boost::zip_iterator использует некоторые сложные внутренние фасады около boost::tuple. По этой причине я также использовал decltype в псевдониме шаблона для ZipRef, чтобы избежать необходимости писать такие неприятные типы внутри выражения лямбда std::for_each.