Luke B.
Luke B.

Reputation: 1288

Inserting iterator range in std::vector

I have a multiset and I'm getting a range from it. I want to add this range in a vector to use it later, this is what I'm doing:

class foo
{
    public:
        int a;
        foo(int a) : a(a){}
};
class FooPointerCompare
{
    public:
        bool operator()(const foo* a, const foo* b)
        {
            return a->a < b->a;
        }
};

std::multiset<foo*, FooPointerCompare> m;
std::vector<std::multiset<foo*, FooPointerCompare>::iterator> v;
auto pair = m.equal_range(new foo(5)); //leak here, I know
v.insert(v.end(), pair.first, pair.second);

but I get these errors:

No matching constructor for initialization of 'std::__1::__tree_const_iterator<foo *, const std::__1::__tree_node<foo *, void *> *, int>'

No viable overloaded '='

when I use a simple for(auto it = pair.first; it != pair.second; it++) v.push_back(it); it works perfectly. What is wrong with my vector::insert call?

Upvotes: 2

Views: 3598

Answers (2)

Steve Jessop
Steve Jessop

Reputation: 279255

vector::insert expects iterators that point to the values to be inserted into the vector.

Since you have a vector of iterators, you would have to pass it something that iterates over the iterators. But you're passing it something that iterates over the elements in your multiset.

So, this fails for the same reason that you can't do:

std::vector<char*> v;
char foo[10];
v.insert(v.end(), foo, foo+10);

or:

std::vector<int> v;
v.insert(v.end(), 0, 10);

One solution to all three problems is boost::counting_iterator. In your case:

v.insert(v.end(),
    boost::make_counting_iterator(pair.first), 
    boost::make_counting_iterator(pair.second)
);

Upvotes: 3

kennytm
kennytm

Reputation: 523274

What's wrong is that

v.insert(v.end(), pair.first, pair.second);

is equivalent to

for (auto it = pair.first; it != pair.second; ++ it)
    v.push_back(*it);
//              ^

which is not the same as your intention. I don't think there's any standard algorithms to do what you want. It's better you just write out the for loop.

Upvotes: 3

Related Questions