decltype of boost::make_zip_iterator?

2019-07-07 07:00发布

问题:

I have the following code:

std::vector<PriceQuote, tbb::scalable_allocator<PriceQuote> > cBids(maxSize);
std::vector<PriceQuote, tbb::scalable_allocator<PriceQuote> > cAsks(maxSize);

auto zipBidsAsks = boost::make_zip_iterator(boost::make_tuple(cBids.begin(), cAsks.begin()));

If I wanted to decltype the return value so that instead of storing it in an auto I can store it in a decltype of whatever boost::make_zip_iterator returns. What does that code look like?

I have tried:

typedef decltype(boost::make_zip_iterator(std::vector<PriceQuote>, std::vector<PriceQuote>)) zipper_type;

// type referred to by zipper_type::iterator
typedef std::iterator_traits<zipper_type::iterator>::value_type zipped_type;

 zipped_type zipBidsAsks = boost::make_zip_iterator(boost::make_tuple(cBids.begin(), cAsks.begin()));

But that doesn't even come close to working. Finally, if I want to iterate over zipBidsAsks and get each <0>, <1>. How is that done?

The access code now gives an error:

    struct PriceBookEventData
{
    timeval ts;
    unsigned totalSize;
    unsigned maxSize;


    typedef decltype
    (
         boost::make_zip_iterator(boost::tuple<std::vector<PriceQuote>::iterator,
                                               std::vector<PriceQuote>::iterator>())
    ) zipper_type;

     zipper_type zipBidsAsks;
};

void AGUI::HandlePriceBookChange(const PriceBookEventData pbed)
{
int k = 0;

while(0 != stop--)
{
    PriceQuote pqb = boost::get<0>(pbed.zipBidsAsks[k]);
    PriceQuote pqa = boost::get<1>(pbed.zipBidsAsks[k]);


/data/cbworkspace/AGUI/AGUI.cpp|101|error: no matching function for call to ‘get(boost::detail::operator_brackets_result<boost::zip_iterator<boost::tuples::tuple<__gnu_cxx::__normal_iterator<PriceQuote*, std::vector<PriceQuote> >, __gnu_cxx::__normal_iterator<PriceQuote*, std::vector<PriceQuote> > > >, boost::tuples::cons<PriceQuote&, boost::tuples::cons<PriceQuote&, boost::tuples::null_type> >, boost::tuples::cons<PriceQuote&, boost::tuples::cons<PriceQuote&, boost::tuples::null_type> > >::type)’|

回答1:

I'm not sure why you want to figure out the type using decltype instead of auto, the latter was designed specifically for cases like this one. Using decltype instead is cumbersome.

You were close with what you tried, except you gave boost::make_zip_iterator a pair of vectors, instead of a tuple of vector interators.

Try this instead

typedef decltype(
  boost::make_zip_iterator(
    boost::tuple<
      std::vector<PriceQuote>::iterator, 
      std::vector<PriceQuote>::iterator>()
  ) 
) zipper_type;

As for iterating over the zip iterator, here's a simple example:

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

int main()
{
    std::vector<int> v1{1,2,3,4}, v2{10,20,30,40};

    std::for_each(
        boost::make_zip_iterator(boost::make_tuple(v1.begin(), v2.begin())),
        boost::make_zip_iterator(boost::make_tuple(v1.end(), v2.end())),
        []( boost::tuple<int, int> const& tup ) {
            std::cout 
              << boost::get<0>(tup) 
              << ", " 
              << boost::get<1>(tup) 
              << std::endl;
        }
    );
}

Output:

1, 10
2, 20
3, 30
4, 40


标签: c++ boost c++11