Формирование союза двух множеств, кажется, дает неправильные и противоречивые ответы

Следующий код является моей попыткой сформировать объединение двухэлементного набора {2,3} с пустым набором {}. Я ожидаю, что результирующий контейнер (в данном случае список) должен иметь размер 2.

Однако когда я запускаю код, я получаю, что размер объединения равен 0 или 3, в зависимости от того, какое из двух указанных мест для объявления переменной united, Ни один из этих результатов не является тем, чего я ожидал, и они явно не могут быть правильными.

Что мне здесь не хватает?

#include <list>
#include <set>
#include <algorithm>
#include <iostream>

using namespace std;

int main()
{
//list<int> united; // resulting output is 3

int d1[] = {2,3};
set<int> dom1(d1, d1+2);
set<int> dom2;

list<int> united; // resulting output is 0

set_union(dom1.begin(), dom1.end(), dom2.begin(), dom2.end(), united.begin());

cout << united.size();

return 0;
}

0

Решение

Если вы посмотрите на документацию std::set_union вы обнаружите, что пятый итератор должен соответствовать требованиям OutputIterator.

Затем, если вы посмотрите на документацию std::list::begin, вы обнаружите, что он возвращает std::list::iterator (или же std::list::const_iterator), который является только BidirectionalIterator который является подтипом InputIterator.

Технически, неконстантный InputIterator также является OutputIterator, но он ведет себя так, что не работает для вашей программы. Итерирует узлы united и copy-назначает исходные элементы поверх уже существующих. Но с тех пор united пусто в вашем случае, итератор выходит за пределы, что приводит к неопределенному поведению.

Простой способ получить OutputIterator, который вставляет новые элементы, состоит в использовании std::back_inserter.

3

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

В общем, всякий раз, когда вы получаете «неправильные и противоречивые ответы», у вас неопределенное поведение, или ваша программа иным образом плохо сформирована без диагностики. Ищите ошибки вне диапазона.

Здесь ваш выходной итератор ссылается на диапазон, который не существует.

Вы должны заменить united.begin() с std::back_inserter(united), так что элементы создаются по мере необходимости.

Это по примеру в cppreference.com std::set_union документация.
Прочитайте документацию!

2

По вопросам рекламы [email protected]