考虑这段代码:
#include <iostream>
#include <string>
int main()
{
std::string str;
std::cout << "Enter a string: \n";
getline(std::cin, str);
}
为什么我必须将std::
用于string
,cin
和cout
,而不是getline()
? getline()
不在标准库中吗?我实际上有点困惑,为什么我不能只在标准库中编写using namespace std;
而不必#include
。提前谢谢!
答案 0 :(得分:13)
这是Andrew Koenig的 * 错误。
他考虑了为用户定义的类型提供运算符的问题。并提出了根据其参数解析函数的想法。例如。如果在std
命名空间中定义了类型的参数,则编译器会在命名空间std
中查找(也)。
这称为Koenig lookup or ADL, Argument Dependent Lookup 的缩写。
using namespace std;
。对于简短的探索性课程,您不仅可以,而且为了节省工作,也可以这样做。
但是,标准库定义了一些标识符,例如distance
非常可能与您使用的名称冲突。
因此,对于更严肃的代码,考虑其他避免冗长的方法是否可能更好。许多程序员甚至认为你不应该在严肃的代码中使用using namespace std;
。一些挪威公司将此作为编码指南(我不同意如此绝对的观点,但你应该知道它存在,并且可能是多数人的观点)。
无论如何:
永远不要在标题
中将using namespace std;
放在全局命名空间中
因为这会使包含标题的某些代码很可能发生distance
之类的名称冲突。
<小时/>
using
无法访问。许多编程语言,例如Java和C#以及Ada和Modula-2以及UCSD Pascal,仅举几例,对单独编译的模块有语言支持,其中模块由函数,变量组成,类型,常数,或许更多。
根据语言的不同,模块可称为“模块”(Modula-2),“包”(Ada,Java),“单位”(Pascal),“类”(Eiffel),依此类推
C ++有一个更原始的单独编译系统,其中编译器本身知道 nothing 关于模块。预处理器可以从“标题”中拖入文本,这提供了获取事物的一致声明的方法。并轻松获得这些声明。
但就是这样,当前的原始文本包含系统存在大量问题,通过各种编译器支持所谓的“预编译头”(不是C ++标准的一部分),大多数问题都显而易见。
David Vandevoorde参与了module proposal for C++。
可悲的是,它还没有为C ++ 11做好准备,但也许它会在以后出现。
*:在评论David Rodriguez中补充说“这不是安德鲁的错。他只将ADL用于运营商,委员会将其扩展到所有功能“。