Следующий код является моей попыткой сформировать объединение двухэлементного набора {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;
}
Если вы посмотрите на документацию 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
.
В общем, всякий раз, когда вы получаете «неправильные и противоречивые ответы», у вас неопределенное поведение, или ваша программа иным образом плохо сформирована без диагностики. Ищите ошибки вне диапазона.
Здесь ваш выходной итератор ссылается на диапазон, который не существует.
Вы должны заменить united.begin()
с std::back_inserter(united)
, так что элементы создаются по мере необходимости.
Это по примеру в cppreference.com std::set_union
документация.
Прочитайте документацию!