【问题标题】:is namespace std defined in multiple headers是在多个头文件中定义的命名空间标准
【发布时间】:2021-10-12 03:45:41
【问题描述】:

我正在尝试理解命名空间std。我知道命名空间是什么。我想知道,命名空间std是否定义在多个头文件中?

我在这里有两个示例代码,它们都可以正常编译和运行。一种使用#include<string>,另一种使用#include<iostream>。两者都使用“使用命名空间标准”。这告诉我std 在两个标题中都定义了,对吗?如果是这样,那么当我在同一代码中使用两个头文件时,编译器如何知道要使用哪个std

代码 1:

#include <string> 
using namespace std;

int main()
{ 
    string test;
    test = "hello"; 
    return 0; 
} 

代码 2:

#include <iostream> 
using namespace std;

int main()
{ 
    string test; 
    test = "hello"; 
    return 0; 
}

【问题讨论】:

  • 如果什么都不包含怎么办?
  • 如果在std 命名空间中定义了类似namespace std { struct something; } 的东西,那么它的完整 名称就是std::something。所以在多个标题中使用namespace std {} 并没有什么坏处,只是定义的所有内容都将具有相同的前缀std::
  • 不同的标题将不同的东西放入namespace std

标签: c++


【解决方案1】:

"这告诉我两个标题中都定义了 std。是 对吧?”

标头包含标准库的部分内容。 iostreamstring 都属于标准库,它们都提供了一组不同的命令,可以用 std:: 来处理。

using namespace 的插入解析了作用域,这意味着编译器在 std::: 内搜索函数或命令,如果在内部作用域中找不到。因此,而不是,例如,写std::cout &lt;&lt; "Hello world" &lt;&lt; std::endl;,你可以简单地写cout &lt;&lt; "Hello world" &lt;&lt; endl;(假设iostream被包括在内)。这缩短并简化了代码的编写,但它也可能有缺点,这就是using namespace std is generally considered bad practice 的原因。

当包含另一个头文件时,会间接包含标准库的某些头文件。您的 Code2 中似乎就是这种情况,尽管缺少 #include&lt;string&gt;,但它仍然可以编译。

不能依赖这种间接包含。可以在此处找到有关此主题的更多信息: Do I have to use #include <string> beside <iostream>?

【讨论】:

  • 默认不是“std::”。如果在内部范围内找不到,则为 std::
  • @PeteBecker 感谢 cmets。我更正了“默认”语句并添加了关于使用“使用命名空间标准”的警告。
【解决方案2】:

所有同名(同一个作用域)的命名空间统一为一个,编译器不必选择。

【讨论】:

    【解决方案3】:

    命名空间已打开;也就是说,您可以从几个单独的命名空间声明中为其添加名称。例如:

    namespace A {
       int f();
    }
    namespace A {
      int g();
    }
    

    【讨论】:

      【解决方案4】:

      我知道命名空间是什么。

      也许你会,也许不完全是。 namespace 是用于防止命名冲突的工具。 (直接)属于命名空间的所有内容都是公共的,因为公共标识符是唯一可能与命名空间之外的代码冲突的标识符。与类不同,没有封装或数据完整性问题需要解决;这些问题被归类到命名空间中的类。

      命名空间的这种开放性意味着,与类定义不同,命名空间定义不必是完整的。您所需要的只是(工作的团队)命名空间的各个部分来协调它们的命名方案。这就是为什么将某些内容添加到其他人的命名空间通常是错误的。由于您不参与协调,因此您可能会无意中引入冲突,可能会悄悄引入未定义的行为,无需诊断。

      不过,从语法上讲,您可以添加到任何命名空间。这是一个有用的特性,因为传统上为每个类创建一个头文件,并且命名空间通常跨越多个类。所以通常需要一个命名空间跨越多个头文件。 How to use namespace across several files?只需在每个命名空间定义中使用相同的命名空间名称。命名空间定义与其说是“定义”,不如说是“游览”。它更像是“这是命名空间的一部分”而不是“这是命名空间”。您看到的游览/部分越多,您的视图就越完整。

      关于名称空间的不完整视图,请参阅Can the definition of a namespace span multiple translation units?(希望您猜“是”。)

      我想知道,命名空间std是否定义在多个头文件中?

      是的。 C++ 标准规定了数十个必须存在的头文件,并且允许实现将它们分解为辅助头文件。请参阅cppreference.com 以获取所需标题的列表; “C 兼容性标头”部分之前列出的那些共同定义了 std 命名空间。

      【讨论】:

        猜你喜欢
        • 2013-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-25
        • 2013-02-08
        • 1970-01-01
        相关资源
        最近更新 更多