Вставка диапазона итератора в std :: vector

У меня есть мультимножество, и я получаю от него диапазон. Я хочу добавить этот диапазон в вектор, чтобы использовать его позже, вот что я делаю:

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);

но я получаю эти ошибки:

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

No viable overloaded '='

когда я использую простую for(auto it = pair.first; it != pair.second; it++) v.push_back(it); это работает отлично. Что не так с моим vector::insert вызов?

2

Решение

Что не так

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

эквивалентно

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

что не совпадает с вашим намерением. Я не думаю, что есть какие-то стандартные алгоритмы, чтобы делать то, что вы хотите. Лучше просто выписать цикл for.

3

Другие решения

vector::insert ожидает итераторы, которые указывают на значения, которые будут вставлены в вектор.

Поскольку у вас есть вектор итераторов, вы должны передать ему что-то, что повторяет итераторы. Но вы передаете это что-то, что перебирает элементы в вашем мультимножестве.

Итак, это не работает по той же причине, что вы не можете сделать:

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

или же:

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

Одним из решений всех трех проблем является boost::counting_iterator. В твоем случае:

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector