如果已经使用名称空间std包括在内,为什么还不必#include <vector>?

时间:2019-05-23 00:09:48

标签: c++ vector stl stdvector

我一直在学习面向对象的计算,尤其是迭代器和标准模板库等。

我似乎不太明白为什么要写

std:vector<int> - //blah, a vector is created.

但是,在某些情况下,您需要写

#include <vector> //to include vector library

这是为什么? 我们通常写“使用命名空间std”的标准库-是否已经包含矢量库?

当我删除定义文件#include时,计算机将无法识别我的矢量变量。

但是,我发现在某些情况下,许多人使用了vector函数,而实际上并没有通过使用std :: vector来声明它。

std::vector<int>::iterator pos;
std::vector<int>coll;

这是其他人使用的代码,似乎可以正常工作吗?

#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>

using namespace std;

int main() {
vector<int>::iterator pos;
vector<int>coll;
}

//这对我有用,但是我想了解为什么这一个起作用而另一个不起作用。

6 个答案:

答案 0 :(得分:1)

using namespace std;指令只是说:“对于std名称空间 中的任何内容,您可以省略std::前缀”。但是如果没有#include <vector>(直接或通过其他#include间接),编译器根本不知道std::vector存在。

标题为您提供了各种类和API的声明(在某些情况下为定义); using namespace声明只是消除了使用命名空间前缀明确限定对它们的引用的需要。

仍然需要执行#include的原因是声明的冲突(您不想只包含每个可能的包含文件,因为其中一些名称的某些定义可能有冲突) ,以及编译性能(#include遍及世界意味着要编译的千字节,甚至不是兆字节),您实际上不会使用的绝大多数代码;将其限制为实际需要的标头意味着更少的磁盘I / O,更少的内存和更少的CPU时间来执行编译。

供以后参考,“我们通常在哪里拧'使用命名空间std;'”表示您已学会了坏习惯。 using namespace std; is frowned upon in production code

答案 1 :(得分:0)

#include <some_file>只是用文件“ some_file”的内容替换了#include指令。

对于#include <vector>,文件“ vector”在vector命名空间中包含类模板std的定义。要声明一个类的实例,该类的定义必须对编译器可见,因此要声明std::vector<int> foo,必须#include <vector>直接或间接地#include #include另一个{ 1}} s。

那么为什么有些代码示例必须#include <vector>而其他代码示例却没有?好吧,他们都做。有些人可能没有明确#include,但他们必须#include另一个执行#include <vector>的文件。

当然,在许多示例中,为了简洁起见,人们只会省略#include。没有正确的#include,代码将无法编译,但是它们会使代码更长,并且可能使作者分心。


语句using namespace std;只是告诉编译器,它应该在std名称空间中搜索在当前名称空间中找不到的所有不合格名称。这意味着编译器可以同时使用名称vectorvector找到std::vector类。

答案 2 :(得分:0)

  

如果您已经使用名称空间std进行了添加,为什么还不必#include?

仅当使用该标头中的声明时,才必须包括<vector>。否则,您不需要包含它。您从不需要 using namespace std;

  

似乎不太了解为什么要写

std:vector<int> - //blah, a vector is created.
     

但是,在某些情况下,您需要写

#include <vector> //to include vector library

如果您创建<vector>对象,则总是必须包含std:vector<int>

  

我们通常在其中编写“使用命名空间std”的标准库-已经包含矢量库了吗?

否,标准库不使用using namespace std;。如果这样做的话,那将使使用std命名空间的全部意图失效。

  

当我删除定义文件#include时,计算机将无法识别我的矢量变量。

这是因为您无法声明尚未定义的类型的变量。 std::vector的定义在<vector>

答案 3 :(得分:0)

首先,std:vector<int> - //blah, a vector is created.不会编译,因为您使用了单个冒号:,这意味着std在这里是label声明。标签名称不能为vector<int>。所以我想你的意思是:std::vector<int>

第二,您可能知道vectoriostream,...是分别在标头<vector><iotream>中定义的库类型...要使用这些类型,您需要必须首先直接或间接包含这些标头。

C ++中的

namespace std是一组标识符,用于减少命名冲突的可能性。在现代C ++中,C ++标准库中的所有功能现在都在命名空间std(标准的缩写)内部定义。

例如查看std::cout;此标识符在类型为std的命名空间ostream中声明。因此,必须首先包含iostream,以便编译器可以看到ostream对象是什么,然后告诉编译器该对象的声明位置? in namespace std。因此仅包含iostream是不够的,因此您可以添加声明了std的命名空间cout的全部内容,或者仅通过以下方式明确告诉编译器声明cout的位置完全合格:

#include <iostream> // contains output/input library types definitions
using std::cout; // ok add only cout definition to the program not the whole content of std.
using namespace std; // contains cout, cin, vector....

答案 4 :(得分:0)

  

如果已经包含使用,为什么不必须包含   名称空间std

看看这个网址:https://en.cppreference.com/w/cpp/header

有100多个头文件供您使用。

恕我直言,您遇到的困惑是这些相同的100多个标头还可供标头作者使用,并且他们还可以访问标准中通常不发布的标头。结果是,例如,当您包含时,其中的一些间接部分也可能会“推入”

我建议您不要在代码中放入“ using namespace std”。它的使用并非故意导致的“隐藏/间接”包含,并且可能不会在下一个实现中使用。

我正在使用g ++ v7.3。我很快就会升级到当前的g ++(我认为是9.x?),除非明确包含它,否则您不能依靠它包含

  

这对我有用,但是我想了解为什么这个对我有用,   另一个没有。

祝你好运...我认为这很糟糕,如果你因此而养成多种不良习惯。


如果您的编译器支持-std = c ++ 17或更高版本,则它具有我喜欢的新功能。新功能使我可以在标头包括头之后立即指定该库中我特别需要的功能。看起来像这样:

#ifndef                 DTB_ENG_FORMAT_HH
#include "../../bag/src/dtb_eng_format.hh"
using DTB::EngFormat_t;
#endif

#ifndef                 DTB_PPLSEM_HH
#include "../../bag/src/dtb_pplsem.hh"
using DTB::PPLSem_t;
#endif

#ifndef                 DTB_ENG_FORMAT_HH
#include "../../bag/src/dtb_eng_format.hh"
#endif

#ifndef                 DTB_ASSERT_HH
#include "../../bag/src/dtb_assert.hh"
#endif

您自己的库可以类似地处理:

mvn appengine:deploy

我尝试跟踪其中的一小部分并将其收集在文件中。当我开始新的尝试时,我会使用较大的列表,并轻而易举地删除“未使用”的功能(当我要发布自己的努力时)。

答案 5 :(得分:-1)

向量是C ++ STL的一部分,可以,但是您需要包括<vector>头文件才能使用它。这就是为什么要使用STL字符串需要#include <string>的原因。包含这些标头后,需要在声明向量或字符串之前使用std::名称空间标识符,以便编译器知道您声明的内容是C ++ STL的一部分,而不是内置于“ base” “ C或C ++。

基本上,using namespace std的作用是使您能够将std::限定符放在stringvector或其他任何内容之前。不推荐这样做,here's一篇文章简要地解释了为什么不应该使用它。相反,如果您想清理代码并且不想每次想打印到控制台时都键入std::,那么可以考虑导入单个标识符,例如using namespace std::cout

希望这会有所帮助。