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


考虑一下这段代码:

#include <iostream>                                                   
#include <string>

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

我为什么要用 std:: 对于 stringcin 和 cout, 但不是 getline()?是 getline() 不在标准库中?我实际上有点困惑为什么我不能写 using namespace std; 而不是必须的 #include 标准库中的任何东西。提前致谢!


5032
2018-01-02 03:23


起源

@norlesh:是的。但那不是问题。 - MSalters


答案:


重新魔术自动命名空间资格。

这是Andrew Koenig的* 故障。

他考虑了为用户定义的类型提供运算符的问题。并提出了根据其参数解析函数的想法。例如。使用命名空间中定义的类型参数 std,编译器在命名空间中查找(也) std

这也叫做 Koenig查找 要么 ADL, 短缺 参数依赖查找


回覆 using namespace std;

对于简短的探索性程序,您不仅可以,而且为了节省工作,您可以这样做。

但是,标准库定义了一些标识符,例如 distance 那是 非常 可能会与您使用的名称发生冲突。

因此,对于更严重的代码,考虑是否其他避免冗长的方法可能会更好。许多程序员甚至认为你 不应该 使用 using namespace std; 严肃的代码。一些挪威公司将此作为编码指南(我不同意如此绝对的观点,但你应该知道它存在,并且可能是多数人的观点)。

好歹:

永远不要放 using namespace std; 在标题中的全局命名空间中

因为那会让名字发生冲突 distance 很可能包含标题的一些代码。


为什么 using 不会让事情变得容易。

许多编程语言,例如Java和C#以及Ada和Modula-2以及UCSD Pascal,仅举几例,对单独编译的模块有语言支持,其中a  由函数,变量,类型,常量组成,可能更多。

根据语言,模块可以被称为“模块”(Modula-2),“包”(Ada,Java),“单元”(Pascal),“类”(Eiffel)等等。

C ++有一个更原始的单独编译系统,基本上编译器本身就知道 没有 关于模块。预处理器可以从“标题”中拖动文本,这提供了一种获取方式 一致的声明 东西的。并轻松获得这些声明。

但就是这样,当前原始文本包含系统存在大量问题,通过各种编译器对所谓的“预编译头”(不是C ++标准的一部分)的支持,最明显可见。

David Vandevoorde曾参与过一项工作 模块提案 对于C ++

可悲的是,它还没有为C ++ 11做好准备,但也许它会在以后发生。

*:在评论中 大卫罗德里格兹 补充说“这不是安德鲁的错。他只将ADL用于运营商,委员会将其扩展到所有功能“。


13
2018-01-02 03:26



+1,但这不是安德鲁的错。他只将ADL用于运营商,委员会将其扩展到所有功能。 - David Rodríguez - dribeas
@ Cheersandhth.-Alf:问题 - 类似于 std::advance,它是否更好用 std::advance(i, d) 或使用 using std::advance; advance(i, d)? - Mehrdad
@Mehrdad:定义“更好”,你有答案。 ;-)个人而言我不会使用资格,因为我认为这只是不必要的冗长,并且可能在某些情况下建立适得其反的习惯。考虑写合格 std::swap(a, b),当a和b是用户定义的类型时。测量某人发现交换通过 std::swap 对于这种类型来说太慢了,所以a friend 功能 swap 被定义为。但它不会被合格者调用 std::swap。这是习惯适得其反的地方(除了冗长/时间考虑)。只是我的看法。 ;-) - Cheers and hth. - Alf