为什么我需要写“std::string"?但不是“std::getline()"?
考虑这段代码:
#include <iostream>
#include <string>
int main()
{
std::string str;
std::cout << "Enter a string:
";
getline(std::cin, str);
}
为什么我必须对 string
、cin
和 cout
使用 std::
,而不是 getline()
?getline()
不在标准库中吗?我实际上有点困惑,为什么我不能只编写 using namespace std;
而不必 #include
标准库中的任何内容.提前致谢!
Why must I use std::
for string
, cin
and cout
, but not getline()
? Is getline()
not in the standard library? I'm actually somewhat confused why I can't just write using namespace std;
and not have to #include
anything in the standard library, too. Thanks in advance!
推荐答案
再神奇的自动命名空间限定.
这是 Andrew Koenig* 的错.
他考虑了为用户定义类型提供运算符的问题.并提出了根据参数解析函数的想法.例如.使用在命名空间 std
中定义的类型参数,编译器(也)在命名空间 std
中查找.
He considered the problem of providing operators for user defined types. And came up with the idea of resolving the function depending on its arguments. E.g. with an argument of type defined in namespace std
, the compiler looks (also) in namespace std
.
这称为 Koenig 查找 或 ADL,Argument Dependent Lookup 的缩写.
That's called either Koenig lookup or ADL, short for Argument Dependent Lookup.
对于简短的探索性程序,您不仅可以,而且为了节省工作量,您应该这样做.
For short exploratory programs you not only can, but to save work you should, do this.
但是,标准库定义了一些标识符,例如 distance
,它们非常可能与您使用的名称发生冲突.
However, the standard library defines some identifiers such as distance
that are very likely to collide with names you use.
因此,对于更严肃的代码,请考虑是否有其他避免冗长的方法可能会更好.许多程序员甚至坚持认为您不应该在严肃的代码中使用 using namespace std;
.一些挪威公司将此作为编码指南(我不同意如此绝对的观点,但您应该知道它存在,并且可能是多数观点).
Hence, for more serious code consider whether other means of avoiding verbosity, might be better. Many programmers even maintain that you should not use using namespace std;
in serious code. Some Norwegian firms have this as a coding guideline (I don't agree with so absolute a view, but you should know that it's there, and may be a majority view).
无论如何:
切勿将 using namespace std;
放在标头的全局命名空间中
Never put a using namespace std;
in the global namespace in a header
因为对于包含标头的某些代码,这很可能导致像 distance
这样的名称冲突.
because that makes name collisions like distance
very likely for some code that includes the header.
<小时>
许多编程语言,例如 Java 和 C#、Ada 和 Modula-2 和 UCSD Pascal,仅举几例,都支持单独编译的模块,其中 模块 由函数、变量组成,类型,常量,也许更多.
Many programming languages, such as Java and C# and Ada and Modula-2 and UCSD Pascal, just to name some, have language support for separately compiled modules, where a module consists of functions, variables, types, constants, maybe more.
根据语言,模块可能被称为模块"(Modula-2)、包"(Ada、Java)、单元"(Pascal)、类"(Eiffel)等等.
Depending on the language a module may be called a "module" (Modula-2), a "package" (Ada, Java), a "unit" (Pascal), a "class" (Eiffel), so on.
C++ 有一个更原始的单独编译系统,其中编译器本质上对模块一无所知.预处理器可以从标题"中拖入文本,这提供了一种获取事物一致声明的方法.并轻松获得这些声明.
C++ has a much more primitive system of separate compilation, where essentially the compiler proper knows nothing about modules. The preprocessor can drag in text from "headers", which provides a way to get consistent declarations of things. And to easily get those declarations.
但仅此而已,当前的原始文本包含系统存在大量问题,通过各种编译器对所谓预编译标头"(不是 C++ 标准的一部分!)的支持最为明显.
But that's all, and the current primitive text inclusion system has a large number problems, most manifestly visible via various compilers' support for so called "precompiled headers" (not part of the C++ standard!).
David Vandevoorde 曾在 C++ 模块提案.
David Vandevoorde has worked on a module proposal for C++.
遗憾的是,它还没有为 C++11 做好准备,但也许以后会来.
Sadly, it wasn't ready for C++11, but maybe it will come later.
*:在评论中 David Rodriguez 补充说这不是 Andrew 的过错.他只打算将 ADL 用于操作员,委员会将其扩展到所有功能.
*: In a comment David Rodriguez adds that “it is not really Andrew's fault. He only intended ADL for operators, the committee extended that to all functions”.
相关文章