2

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

我似乎不太明白为什么如果你写

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

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

#include <vector> //to include vector library

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

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

但是,在某些情况下,我看到很多人使用了向量函数而没有通过使用 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;
}

// 这对我有用,但我想了解为什么这个有效而另一个无效。

4

6 回答 6

5

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

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

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

为了将来参考,“我们通常写'using namespace std;'”表示你已经被教坏习惯。using namespace std; 在生产代码中不受欢迎

于 2019-05-23T00:18:43.593 回答
1

如果您已经包含使用名称空间标准,为什么您不必#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>

于 2019-05-23T00:43:03.510 回答
1

如果您已经包含 using namespace std,为什么不必包含 <vector>

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

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

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

我建议您不要在代码中添加“使用命名空间标准”。它的使用并没有故意导致 <vector> 的“隐藏/间接”包含,并且可能不会在下一个实现中。

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

这对我有用,但我想了解为什么这个有效而另一个无效。

只是运气......我认为不好,如果你因为它开始了多个坏习惯。


如果你的编译器支持 -std=c++17 或更好,它有一个我喜欢的新特性。新功能允许我在包含头文件之后立即指定该库中我特别需要的函数。它看起来像这样:

#include <iostream>
using std::cout, std::cerr, std::endl, std::flush,
      std::hex, std::dec, std::cin;

#include <iomanip>
using std::setw, std::setfill;

#include <string>
using std::string, std::to_string;

#include <thread>
using std::thread, std::this_thread::sleep_for;

#include <vector>
using std::vector;

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

#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

我尝试跟踪其中的一小部分,并将它们收集到一个文件中。当我开始一项新工作时,我会使用更大的列表,并简单地删除“未使用”的功能(当我想发布我的工作时)。

于 2019-05-23T01:41:14.790 回答
0

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

在 的情况下#include <vector>,文件“vector”包含命名空间中类模板的vector定义std。要声明一个类的实例,该类的定义必须对编译器可见,因此要声明std::vector<int> foo必须#include <vector>,直接或间接通过#include另一个文件来声明#include它。

那么为什么有些代码示例必须这样做#include <vector>而其他代码示例不需要呢?嗯,他们都这样做。有些人可能没有#include明确表示,但他们必须#include是另一个文件#include <vector>

当然,在许多示例片段中,为了简洁起见,人们会简单地省略#includes。如果没有正确的 s,代码将无法编译#include,但它们会使代码更长,并且可能会分散作者试图提出的观点。


该语句using namespace std;只是告诉编译器它应该在命名空间中搜索std它在当前命名空间中找不到的任何非限定名称。这意味着编译器可以vector通过名称vectorstd::vector.

于 2019-05-23T00:22:40.767 回答
0

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

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

namespace std在 C++ 中是一组标识符,用于减少命名冲突的可能性。在现代 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....
于 2019-05-23T01:25:13.010 回答
-1

向量是 C++ STL 的一部分,是的,但是您需要包含<vector>头文件才能使用它。#include <string>如果您想使用 STL 字符串,这与您需要这样做的原因相同。包含这些头文件后,您需要std::在声明向量或字符串之前使用命名空间标识符,以便编译器知道您声明的内容是 C++ STL 的一部分,而不是“基础”C 或 C++ 的内置内容。

基本上,这样using namespace std做是让你能够在你的或其他东西std::之前放弃预选赛。不建议这样做,这里有一篇文章简要解释了为什么你不应该使用它。相反,如果您想清理代码并且不想在每次打印到控制台时都键入,那么请考虑导入单个标识符,例如。stringvectorstd::using namespace std::cout

希望这可以帮助。

于 2019-05-23T00:29:15.033 回答