Это C ++, а не Java [edit: или .NET]. Вы почти наверняка захотите заменить (например):
set<Line *> * newSet = new set<Line *>();
только с:
set<Line *> newSet;
... или, что еще лучше, вероятно, просто:
set<Line> newSet;
Хотя невозможно сказать наверняка, основываясь на коде, который вы разместили, но вполне вероятно, что ваши left
и right
тоже не должны иметь дело с указателями - если они собираются это делать Что-нибудь в этом роде, ссылка, вероятно, имеет больше смысла (хотя, как я уже сказал, основываясь только на том, что вы опубликовали, невозможно сказать наверняка).
Как только вы это сделаете, вы столкнетесь с небольшой проблемой: «нормальный» итератор над set
(или multiset
, map
или multimap
) действительно является const_iterator. После того, как вы вставите что-то в ассоциативный контейнер, вам не разрешено его менять, потому что это может уничтожить инвариант коллекции (будучи отсортированным). Если вы хотите изменить существующий элемент, вам нужно удалить его из содержимого, внести изменения и вставить измененный объект обратно в контейнер. В вашем случае вы просто вставляете новые элементы, поэтому вам нужен insert_iterator
.
Поскольку вы не планируете модифицировать left
или right
, вы можете также рассматривать их как const
:
std::set_union(left.cbegin(), left.cend(),
right.cbegin(), right.cend(),
std::inserter(newSet, newSet.end()));
Если вы решите имитировать set_union самостоятельно, вы можете сделать что-то вроде этого:
std::set<Line> newSet(left.cbegin(), left.cend());
std::copy(right.cbegin(), right.cend(), std::inserter(newSet, newSet.end()));
Редактировать:
Вместо того, чтобы передавать указатели на контейнеры, вы обычно хотите передавать итераторы в контейнеры. Например, чтобы распечатать содержимое, у вас теперь есть что-то вроде:
void print_data(std::vector<Line *> const *data) {
for (int i=0; i<data->size(); i++)
std::cout << *(*data)[i] << "\n";
}
Возможно, он имеет больше форматирования и тому подобное, но на данный момент мы проигнорируем эти детали и предположим, что это так просто. Чтобы записать данные непосредственно из выбранного вами контейнера, обычно требуется шаблон, который будет принимать итераторы произвольного типа:
template <class inIt>
void print_data(inIt begin, inIt end) {
while (begin != end)
std::cout << *begin++ << '\n';
}
Однако мы можем пойти еще дальше и указать вывод в качестве итератора:
template <class inIt, class outIt>
void print_data(inIt begin, inIt end, outIt dest) {
while (begin != end) {
*dest++ = *begin++;
*dest++ = '\n';
}
}
Вы можете сделать еще один шаг и позволить пользователю указать разделитель, который будет использоваться между элементами, вместо того, чтобы всегда использовать '\ n', но в этот момент вы просто дублируете что-то, что уже есть в стандартная библиотека - комбинация std::copy
и std::ostream_iterator
, как вы, вероятно, захотите с этим справиться в реальности:
std::copy(newSet.begin(), newSet.end(),
std::ostream_iterator<Line>(std::cout, "\n"));
Однако обратите внимание, что для стандартной библиотеки ostream_iterator
- это просто еще один итератор. Если вы просто собираетесь распечатать объединение left
и right
, вы можете пропустить даже создание набора для хранения этого объединения и просто распечатать его напрямую:
std::set_union(left.cbegin(), left.cend(),
right.cbegin(), right.cend(),
std::ostream_iterator<Line>(std::cout, "\n"));
Тот факт, что ostream_iterator
пишет в файл вместо того, чтобы помещать вещи в обычную коллекцию, совершенно не имеет отношения к стандартной библиотеке. Он имеет несколько классов итераторов и может записывать выходные данные в любой итератор, моделирующий правильный класс.
Теперь я могу прыгнуть, так сказать, - возможно, потребуется выполнить другую обработку данных, прежде чем записать их на консоль. Суть не в том, что вам обязательно нужно записывать объединение непосредственно в стандартный вывод, а просто в том, что вам не обязательно записывать его в какую-либо другую коллекцию, прежде чем распечатать.