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;
}
4

2 回答 2

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.

于 2016-04-04T14:43:38.557 回答
2

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

在这里,您的输出迭代器引用了一个不存在的范围。

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

这是根据cppreference.comstd::set_union文档中的示例。
阅读文档!

于 2016-04-04T14:43:38.993 回答