我听说过使用名称空间std;这是不好的做法,我应该直接使用std::cout和std::cin。这是为什么?声明与std命名空间中的某个变量同名的变量是否有风险?


当前回答

根据我的经验,如果你有多个库使用cout,但出于不同的目的,你可能会使用错误的cout。

例如,如果我键入,使用名称空间std;并使用命名空间otherlib;如果只键入cout(恰好两者都有),而不是std::cout(或'otherlib::cout'),则可能会使用错误的一个,并出现错误。使用std::cout更有效。

其他回答

是的,名称空间很重要。在我的项目中,我需要将一个var声明导入到源代码中,但在编译时,它与另一个第三方库冲突。

最后,我不得不用其他方法来解决这个问题,并使代码变得不那么清晰。

有经验的程序员使用任何解决他们问题的方法,避免任何产生新问题的方法。出于这个确切的原因,他们避免使用头文件级别的指令。

经验丰富的程序员也尽量避免在源文件中使用完全限定的名称。这样做的一个次要原因是,除非有充分的理由,否则在代码较少的情况下编写更多的代码是不优雅的。一个主要原因是关闭参数依赖查找(ADL)。

这些好理由是什么?有时程序员明确希望关闭ADL,有时他们希望消除歧义。

因此,以下内容是可以的:

函数级使用指令并在函数的实现中使用声明使用源文件内声明的源文件级别(有时)使用指令的源文件级别

命名空间是为了避免命名冲突。C++基于C,C在函数和变量名方面有很多问题,因为有时来自不同库的函数会发生冲突。因此,库开发人员开始在其函数前面加上库名,如下所示:

foo/foo.h:

void libfoo_foo_foo_h_open(); // the name can be weird then even this one!

C++引入了名称空间,以一种简单的方式解决了这个问题。

假设您有两个名为file和window的库,分别处理文件和窗口,代码如下:

#include <file.h>
#include <window.h>

using namespace file;
using namespace window;

void open() {
     ...
}

文件.h:

namespace file {
    void open(); // What!
}

window.h:

namespace window {
    void open(); // Oh no!
}

上面的代码肯定无法编译。

如果你不喜欢键入std::(只有5个字符),你可以一直这样做:(在头文件中不是个好主意)

using s = std;

如果您仍然想使用名称空间std;在您的源文件中,那么您正在引发这个问题,我必须问您“NAMESPACE的目的是什么?”。

命名空间是命名作用域。命名空间用于对相关声明进行分组并保持独立项目分开。例如,两个单独开发的库可以使用相同的名称来表示不同的项,但用户仍然可以同时使用这两个:

namespace Mylib{
    template<class T> class Stack{ /* ... */ };
    // ...
}

namespace Yourlib{
    class Stack{ /* ... */ };
    // ...
}

void f(int max) {
    Mylib::Stack<int> s1(max); // Use my stack
    Yourlib::Stack    s2(max); // Use your stack
    // ...
}

重复名称空间名称可能会分散读者和作者的注意力。因此,有可能声明来自特定命名空间的名称在没有明确限定的情况下可用。例如:

void f(int max) {
    using namespace Mylib; // Make names from Mylib accessible
    Stack<int> s1(max); // Use my stack
    Yourlib::Stack s2(max); // Use your stack
    // ...
}

命名空间为管理不同库和不同版本的代码提供了强大的工具。特别是,它们为程序员提供了如何明确引用非本地名称的备选方案。

来源:C++编程语言概述作者:Bjarne Stroustrup

有一个非常简单的答案:这是防御性编程。您知道,使用名称空间std;-可以使std::size_t、std::cout等的使用更容易一些我希望您不必相信这样的指令在标题中没有位置!然而,在翻译单元中,您可能会受到诱惑。。。

作为std命名空间一部分的类型、类等随着每次C++修订而增加。如果放松std::限定符,可能会有太多的歧义。放松std中经常使用的名称的限定符是完全合理的,例如,使用std::fprintf;,或者更可能的是:使用std::size_t;-但是,除非这些已经是语言的很好理解的部分(或者特别是C库的std包装),否则只使用限定符。

当您可以使用typedef并结合自动和decltype推理时,从可读性/可维护性的角度来看,实际上没有什么好处。