2016-04-04 21 views
0

Следующий код - моя попытка сформировать объединение набора двух элементов {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; 
} 

ответ

3

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

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

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

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

2

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

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

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

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