是否有必要包含头<iterator>来使用开始和结束函数?

时间:2016-08-12 21:21:54

标签: c++

要获取指向数组的第一个和最后一个元素的指针,我们可以使用开始和结束函数:https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-tests.md#conformance-tests

但是,我注意到如果省略#include <iterator>,程序编译得很好。为什么会出现这种情况,因为这些函数是在<iterator>标题中定义的?

我使用的唯一标题是<iostream> 我使用的程序:https://stackoverflow.com/a/14595314/5761266

4 个答案:

答案 0 :(得分:2)

在C ++实现中,您使用的其他标头之一很可能包括ItemsControl。不要指望这在其他C ++实现中是相同的,甚至不是您正在使用的实现的下一个版本。

最佳做法是始终在所需文件中包含所需的所有标题。

如果包含从另一个包含的标题中删除,或者看起来像包含的结果仅仅是关键类或函数的前向声明,这可以防止将来出现问题和神秘错误。

这也有助于提高便携性。您使用的下一个工具链可能有不同的布局,更不用说可能继承您的代码或希望在另一个项目中使用它的其他程序员。

从学生编码器的角度来看,当您提交编译在PC上的代码时,它真的很糟糕,而不是标记符。

这听起来很愚蠢和重复,但正确编写的标题有include guards,以防止标题在任何translation unit中包含多个标题。

这也为其他开发人员留下了面包屑,他们可以一目了然地看到给定文件使用的标头。出于这个原因,请不要包含所有内容以防可能需要它。创建一个不必要的标题的整体列表也会减慢编译速度。

答案 1 :(得分:2)

必须事先完全定义函数的返回类型。这意味着迭代器头必须包含在定义begin()end()方法的任何可迭代对象中,并返回一个完整的迭代器对象 *

这意味着无论何时使用标准容器(例如std::vectorstd::mapstd::list等),标准库头文件必须#include <iterator>之前的某个地方声明了begin()end()方法。

因此,您自己不需要#include <iterator>,因为通过执行#include <vector>(例如),您也会自动包含iterator.h。

请记住,当您#include一个头文件时,该头文件中包含的任何其他头文件也会在您的代码文件中自动#include

*除非迭代器类型完全是自定义的且不使用standard iterator heirarchy categories

答案 2 :(得分:1)

从C ++ 14开始,功能模板

  • std::begin
  • std::end
  • std::cbegin
  • std::cend
  • std::rbegin
  • std::rend
  • std::crbegin
  • std::crend

不仅由<iterator>提供,还由

提供
  • <array>
  • <deque>
  • <forward_list>
  • <list>
  • <map>
  • <regex>
  • <set>
  • <string>
  • <unordered_map>
  • <unordered_set>
  • <vector>

正如其他人所提到的,其他标题也允许包含<iterator>,但这不能保证,并且可能会从一个实现更改为另一个实现。

答案 3 :(得分:0)

迭代器的基本功能如&#39;开始&#39;并且&#39;结束&#39;包含在其他STL中,如map,vector,因此您不需要显式包含迭代器,但是如果您想使用迭代器功能,例如&#39; istream_iterator&#39;或者&#39; back_inserter&#39;,您必须在程序中包含迭代器。