由set_union()返回的迭代器

时间:2014-04-02 03:56:22

标签: c++ c++11 stl

我使用算法stl:

中的set_union()获得以下C ++代码
 9     int first[] = {5, 10, 15, 20, 25};
10     int second[] = {50, 40, 30, 20, 10};
11     vector<int> v(10);
12     vector<int>::iterator it;
13
14     sort(first, first+5);
15     sort(second, second+5);
16
17     it = set_union(first, first + 5, second, second + 5, v.begin());
18
19     cout << int(it - v.begin()) << endl;

我从http://www.cplusplus.com/reference/algorithm/set_union/阅读了set_union的文档。我有两个问题:

  • 第17行。我理解set_union()正在返回一个OutputIterator。一世 思想迭代器就像从容器对象返回的对象 (例如实例化的vector类,并调用blah.begin() 返回迭代器对象)。我想知道是什么 “it”从set_union返回指向哪个对象?
  • 第19行。“它 - v.begin()”等同于什么。我猜的是“8”的输出值,联合的大小,但是怎么样?

如果有人可以解释一下,我会非常感激。

谢谢你, 艾哈迈德。

2 个答案:

答案 0 :(得分:1)

set_union的文档声明返回的迭代器指向超出构造范围的末尾,在您的情况下是v中由set_union写入的最后一个元素的一个。it - v.begin()

这就是vector<T>::iterator导致集合联盟长度的原因。请注意,您只能简单地减去两者,因为std::distance必须满足RandomAccessIterator概念。理想情况下,您应该使用int first[] = {5, 10, 15, 20, 25}; int second[] = {50, 40, 30, 20, 10}; std::vector<int> v; v.reserve(10); // reserve instead of setting an initial size sort(std::begin(first), std::end(first)); sort(std::begin(second), std::begin(second)); // use std::begin/end instead of hard coding length auto it = set_union(std::begin(first), std::end(first), std::begin(second), std::end(second), std::back_inserter(v)); // using back_inserter ensures the code works even if the vector is not // initially set to the right size std::cout << std::distance(v.begin(), it) << std::endl; std::cout << v.size() << std::endl; // these lines will output the same result unlike your example 来计算两个迭代器之间的间隔。

您的代码段可以更加惯用地编写,如下所示:

vector

回复您的评论

  

创建大小为10或保留大小为10的向量有什么用?

在原始示例中,创建初始大小至少为8的set_union是必要的,以防止未定义的行为,因为vector将8个元素写入输出范围。保留10个元素的目的是优化以防止set_union的多次重新分配的可能性。这通常不需要或不可行,因为您不会事先知道结果的大小。

  

我试过尺码1,工作正常

大小为1肯定不能正常使用您的代码,它是未定义的行为。 vector将在set_union的末尾写出来。出于同样的原因,您会得到大小为0的seg错误。没有必要推测为什么在第一种情况下不会发生同样的事情,这只是未定义行为的本质。

  

set_union是否修剪了向量的大小,从10到8.为什么或者是set_union()的工作原理

您只是将迭代器传递给vector::push_back(),它知道没有关于底层容器。因此,如果需要,它无法修剪多余的元素,或者为更多元素腾出空间。它只是继续写入输出迭代器并在每次写入后递增迭代器。这就是为什么我建议使用back_inserter,这是一个迭代器适配器,只要写入迭代器就会调用set_union。这可以保证vector永远不会超出{{1}}的范围。

答案 1 :(得分:0)

首先:&#34;它&#34;是构造范围末尾的迭代器(即等效于v.end())

第二:它 - v.begin()等于8,因为向量迭代器通常只是typedefed指针,因此它只是做指针运算。通常,使用距离算法比依赖原始减法更好

cout << distance(v.begin(), it) << endl;