为什么我需要写“std :: string”而不是“std :: getline()”?

时间:2014-01-02 03:23:25

标签: c++ include std

考虑这段代码:

#include <iostream>                                                   
#include <string>

int main()
{
  std::string str;
  std::cout << "Enter a string: \n";
  getline(std::cin, str);
}

为什么我必须将std::用于stringcincout,而不是getline()getline()不在标准库中吗?我实际上有点困惑,为什么我不能只在标准库中编写using namespace std;而不必#include。提前谢谢!

1 个答案:

答案 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用于运营商,委员会将其扩展到所有功能“。