形成两套联合似乎给出了错误和不一致的答案

时间:2016-04-04 14:29:08

标签: c++ stdset set-union

以下代码是我尝试使用空集{}形成两个元素集{2,3}的并集。我希望生成的容器(在这种情况下,列表)的大小应为2.

但是,当我运行代码时,我得到了union的大小为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;
}

2 个答案:

答案 0 :(得分:3)

如果您查看std::set_union的文档,您会发现第五个迭代器必须符合OutputIterator的要求。

然后,如果你看一下std::list::begin的文档,你会发现它返回std::list::iterator (or std::list::const_iterator),它只是一个BidirectionalIterator,它是一个子类型InputIterator

从技术上讲,非const InputIterator也是一个OutputIterator,但其行为方式对您的程序不起作用。它迭代united的节点,并在已存在的元素上复制分配源元素。但由于united在您的情况下为空,因此迭代器超出范围,导致未定义的行为。

获取插入新元素的OutputIterator的简便方法是使用std::back_inserter

答案 1 :(得分:2)

一般情况下,每当你得到错误且不一致的答案时,你就会有不确定的行为,或者你的程序在没有被诊断出来的情况下是不正确的。寻找超出范围的错误。

此处,输出迭代器是指不存在的范围。

您应该将united.begin()替换为std::back_inserter(united),以便根据需要创建元素。

这是the cppreference.com std::set_union documentation中的示例 阅读文档!