У меня есть мультимножество, и я получаю от него диапазон. Я хочу добавить этот диапазон в вектор, чтобы использовать его позже, вот что я делаю:
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
вызов?
Что не так
v.insert(v.end(), pair.first, pair.second);
эквивалентно
for (auto it = pair.first; it != pair.second; ++ it)
v.push_back(*it);
// ^
что не совпадает с вашим намерением. Я не думаю, что есть какие-то стандартные алгоритмы, чтобы делать то, что вы хотите. Лучше просто выписать цикл for.
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)
);