Reputation: 1288
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
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
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