【问题标题】:Namespaces and the Pre-Processor命名空间和预处理器
【发布时间】:2013-01-25 10:25:34
【问题描述】:

我在理解 C++ 中的预处理器和命名空间时遇到了一些麻烦。例如,考虑以下程序:

#include <iostream> 

int main() 
{
    using namespace std;

    cout << "Hello World!" << endl;

    return 0; 
}

所以当这个程序准备被编译时,预处理器将识别#include指令并将iostream文件添加到程序中,以便程序具有I/O能力(即“cout”和“endl”) .现在,根据我的教科书,作为 C++ 编译器标准组件的类、函数和变量被放置在命名空间 std 中。

这很令人困惑,因为如果将标准函数(“cout”和“endl”)放在这个命名空间中,iostream 的用途是什么?我基本上是想了解为什么我们需要 iostream 和一些有关正在使用的命名空间的信息。

【问题讨论】:

    标签: c++ compiler-construction


    【解决方案1】:

    严格来说,你不需要using namespace std;,它所做的只是让你写

    cout << "Hello World!" << endl;
    

    而不是

    std::cout << "Hello World!" << std::endl;
    

    名称空间“包含”iostream 定义(以及标准 C++ 库提供的其他定义),仅在 std:: 隐含地“前缀”到所有名称的意义上。这个“包含”不同于“iostream 文件包含输入/输出函数的定义”中的“包含”:文件字面上包含定义; std:: 命名空间名称只是一个前缀,可让您避免名称冲突。

    【讨论】:

    • 所以如果我理解正确,iostream 文件包含“cout”和“endl”的实际定义,而命名空间包含 iostream 定义以及其他定义。包含有关命名空间的信息(即以 std:: 为前缀或声明“使用命名空间 std;”)以避免名称冲突的唯一原因是什么?已经包含您需要的所有定义(通过预处理器步骤)似乎有点奇怪,您仍然需要提供有关命名空间的更多信息
    • @Ockham 我不会在命名空间中使用“包含”一词以避免混淆。这里唯一真正的包含是“iostream 包含coutendl 的定义”。在 iostream 中,这些定义封闭std 命名空间内。 cout 的“真实姓名”(也称为“全名”)是std::cout。当您输入 using 指令时,编译器会将 std:: 隐式添加到 unqualified 名称(即不存在范围解析运算符 :: 的名称)以解析它们的定义。不过,using 是完全可选的。
    • 另外,using namespace std; 是有问题的,因为它会污染命名空间,尤其是当您包含更多标准标头时。 (函数内部没有文件级别那么糟糕,但我仍然认为这不是一个好主意,using std::cout;using std::endl 更好。
    【解决方案2】:

    头文件&lt;iostream&gt;包含几个有用的东西的声明,包括变量std::coutstd::endl

    如果没有这些声明,编译器将不会知道您在编写 cout &lt;&lt; ... 时所指的是什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      • 2011-09-05
      • 2021-08-02
      • 1970-01-01
      相关资源
      最近更新 更多