【问题标题】:What requires me to declare "using namespace std;"?什么需要我声明“使用命名空间 std;”?
【发布时间】:2011-01-14 03:48:42
【问题描述】:

这个问题可能是重复的,但我找不到一个好的答案。简简单单,需要我声明什么

using namespace std;

在 C++ 程序中?

【问题讨论】:

    标签: c++ namespaces include using using-directives


    【解决方案1】:

    自从 C++ 标准被接受以来,几乎所有的标准库都在 std 命名空间内。因此,如果您不想使用 std:: 限定所有标准库调用,则需要添加 using 指令。

    然而,

    using namespace std;
    

    被认为是一种不好的做法,因为您实际上是在导入整个标准命名空间,从而为名称冲突提供了很多可能性。最好只导入你在代码中实际使用的东西,比如

    using std::string;
    

    【讨论】:

    • 我可以在一行中包含来自 std 的多个元素吗,例如: using std::string, std::make_shared;
    【解决方案2】:

    什么都不做,这是避免在该命名空间中的所有内容前加上 std:: 前缀的简写:

    【讨论】:

    • 而且也被认为是不好的做法。
    • 如果你在全局命名空间中执行它是不好的做法:D
    • @GMan, @Hassan:在实现文件中使用它非常好,但在头文件中使用它是危险的。为什么每个人都在说“糟糕的做法”?我不想处理必须在所有地方输入std:: 的代码,就像我不想使用using namespace some_tools; 隐式导入任何命名空间一样
    • 这是不好的做法,因为它更有可能导致名称冲突。最好一次导入一个符号:例如using std::string
    【解决方案3】:

    从技术上讲,您可能需要使用 using(对于整个命名空间或单个名称)才能使用 Argument Dependent Lookup。

    考虑以下两个使用swap() 的函数。

    #include <iostream>
    #include <algorithm>
    
    namespace zzz
    {
        struct X {};
    
    
    void swap(zzz::X&, zzz::X&) 
    {
        std::cout << "Swapping X\n";
    }
    }
    
    template <class T>
    void dumb_swap(T& a, T& b)
    {
        std::cout << "dumb_swap\n";
        std::swap(a, b);
    }
    
    template <class T>
    void smart_swap(T& a, T& b)
    {
        std::cout << "smart_swap\n";
        using std::swap;
        swap(a, b);
    }
    
    int main()
    {
        zzz::X a, b;
        dumb_swap(a, b);
        smart_swap(a, b);
    
        int i, j;
        dumb_swap(i, j);
        smart_swap(i, j);
    }
    

    dumb_swap 总是调用std::swap - 即使我们更喜欢使用zzz::swap 来处理zzz::X 对象。

    smart_swap 使std::swap 可见作为一个备用选项(例如,当使用整数调用时),但由于它不完全限定名称,zzz::swap 将通过 ADL 用于zzz::X


    主观上,是什么迫使我使用using namespace std; 是编写使用各种标准函数对象等的代码。

    //copy numbers larger than 1 from stdin to stdout
    remove_copy_if(
        std::istream_iterator<int>(std::cin), std::istream_iterator<int>(),
        std::ostream_iterator<int>(std::cout, "\n"),
        std::bind2nd(std::less_equal<int>(), 0)
    );
    

    IMO,在这样的代码中 std:: 只会产生线路噪音。

    如果在实现文件中使用using namespace std;,在这种情况下我不会发现它是令人发指的罪行(但它甚至可以被限制在函数范围内,就像在交换示例中一样)。

    绝对不要将 using 语句放在头文件中。原因是这会污染其他标头的名称空间,这些标头可能包含在有问题的标头之后,可能导致其他标头中的错误可能不受您的控制。 (它还增加了令人惊讶的因素:包括该文件的人可能不希望看到所有类型的名称。)

    【讨论】:

      【解决方案4】:

      无需显式引用std::member 即可引用std 命名空间中的成员的能力。例如:

      #include <iostream>
      using namespace std;
      
      ...
      cout << "Hi" << endl;
      

      对比

      #include <iostream>
      
      ...
      std::cout << "Hi" << std::endl;
      

      【讨论】:

        【解决方案5】:

        你绝对不应该说:

        using namespace std;
        

        在您的 C++ 标头中,因为这超出了使用命名空间的全部意义(这样做会构成“命名空间污染”)。以下是有关此主题的一些有用资源:

        1) Standard convention for using “std” 上的 stackoverflow 线程

        2) Herb Sutter 在Migrating to Namespaces 上的一篇文章

        3) FAQ 27.5 来自 Marshall Cline 的 C++ Faq lite。

        【讨论】:

          【解决方案6】:

          首先,这在 C 中不是必需的 - C 没有命名空间。在 C++ 中,std 命名空间中的任何内容,包括大部分标准库。如果你不这样做,你必须像这样显式地访问命名空间的成员:

          std::cout << "I am accessing stdout" << std::endl;
          

          【讨论】:

            【解决方案7】:

            首先,在 C 中从不需要 using 指令,因为 C 根本不支持命名空间。

            using 指令在 C++ 中从不真正必需,因为命名空间中的任何项目都可以通过在它们前面加上 std:: 来直接访问。所以,例如:

            using namespace std;
            string myString;
            

            相当于:

            std::string myString;
            

            您是否选择使用它是一个偏好问题,但是公开整个std 命名空间以节省一些击键通常被认为是不好的形式。仅公开命名空间中特定项目的另一种方法如下:

            using std::string;
            string myString;
            

            这允许您仅公开您特别需要的 std 命名空间中的项目,而不会有无意中公开您不打算公开的内容的风险。

            【讨论】:

              【解决方案8】:

              命名空间是一种包装代码的方式,以避免混淆和名称冲突。例如:

              文件 common1.h:

              namespace intutils
              {
                  int addNumbers(int a, int b)
                  {
                      return a + b;
                  }
              }
              

              使用文件:

              #include "common1.h"    
              int main()
              {
                  int five = 0;
                  five = addNumbers(2, 3); // Will fail to compile since the function is in a different namespace.
                  five = intutils::addNumbers(2, 3); // Will compile since you have made explicit which namespace the function is contained within.
              
                  using namespace intutils;
                  five = addNumbers(2, 3); // Will compile because the previous line tells the compiler that if in doubt it should check the "intutils" namespace.
              }
              

              因此,当您编写 using namespace std 时,您所做的只是告诉编译器,如果有疑问,它应该在 std 命名空间中查找函数等,它无法找到定义。这在示例(和生产)代码中很常用,因为它使键入 cout 之类的常用函数等比必须将每个函数完全限定为 std::cout 更快。

              【讨论】:

                【解决方案9】:

                你永远不必声明 using namespace std;使用它是不好的做法,你应该使用 std:: 如果你不想输入 std:: 总是在某些情况下你可以做这样的事情:

                using std::cout;
                

                通过使用 std::,您还可以判断程序的哪些部分使用标准库,哪些不使用。更重要的是可能与包含的其他功能发生冲突。

                Rgds 莱恩

                【讨论】:

                • 在头文件的全局命名空间中这只是不好的做法。在实现文件中,这通常是一个好主意。保存打字是无关紧要的——你的编辑应该为你打字。这很好,因为它使代码比在任何地方都有std:: 更具可读性,并且比在每个文件的顶部有三十行using std::whatever; 更易于维护。
                【解决方案10】:

                C++ 标准库中的所有文件都在 std 命名空间中声明其所有实体。
                例如:使用 iostream 中定义的cin,cout

                替代方案:

                using std::cout;
                using std::endl;
                cout << "Hello" << endl;
                std::cout &lt;&lt; "Hello" &lt;&lt; std::endl;

                【讨论】:

                  【解决方案11】:

                  没有什么要求你做的——除非你是 C++ 标准库的实现者并且你想在以“新”和“旧”风格声明头文件时避免代码重复:

                  // cstdio
                  namespace std
                  {
                    // ...
                    int printf(const char* ...);
                    // ...
                  }
                  

                  .

                  // stdio.h
                  #include <cstdio>
                  using namespace std;
                  

                  好吧,当然示例有些做作(您同样可以使用普通的&lt;stdio.h&gt; 并将其全部放在&lt;cstdio&gt; 的std 中),但Bjarne Stroustrup 在他的The C++ Programming Language 中显示了这个示例。

                  【讨论】:

                    【解决方案12】:

                    每当您使用在命名空间中声明的内容时都会使用它。 C++ 标准库在命名空间 std 中声明。因此你必须这样做

                    using namespace std;
                    

                    除非你想在另一个命名空间中调用函数时指定命名空间,像这样:

                    std::cout << "cout is declared within the namespace std";
                    

                    您可以在http://www.cplusplus.com/doc/tutorial/namespaces/ 阅读更多相关信息。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-12-10
                      • 2015-02-10
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多