关于命名空间:C++ “using std::” 和每次 calling std::

C++ “using std::<type>” vs calling std::<type> every time

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Using std Namespace
Why is 'using namespace std;' considered a bad practice in C++?

假设我在C++中使用EDCOX1,0,我正在编写一个打印语句。我可以选择:

1
2
3
using namespace std;
[...]
cout <<"Hello" << endl;

1
2
3
4
using std::cout;
using std::endl;
[...]
cout <<"Hello" << endl;

1
std::cout <<"Hello" << std::endl;

我相信,也许这是不正确的,第一个应该避免,因为它会给你的程序增加很多不必要的膨胀。但是,我不知道第二种和第三种风格在性能上是否有任何区别。我看到的大多数使用库的代码都倾向于使用第三种样式;但是对于我来说,如果在使用第二种样式时没有权衡的话,它似乎是最干净、最可读的方法,特别是当您对有问题的函数或对象进行了大量调用时。

有人能启发我吗?


无论您选择哪种方式,都没有性能差异或"膨胀"。

但是,如果你这样做,例如

1
2
using namespace std;
using namespace boost;

两个名称空间中的名称冲突会给您带来很多麻烦。

我认为版本3,在任何地方使用std::cout等,更容易阅读,并且可以避免将来的名称冲突。

如果这不是您想要的,选项2是第二好的,因为它只从名称空间中引入了一些选择名称。注意,尽管在您的示例中,由于using声明包含的字符比您在代码的其余部分中不键入std::所节省的字符多,因此在键入时会出现净损失。


我的经验法则是:永远不要把using namespace放在a.h中,而是可以在.cpp文件中随意使用。尤其是当它是using namespace std


每种方法产生的代码应该完全相同。从一开始就不会有任何膨胀,因为它只会在编译时将来自std的所有名称提供给代码——不使用的内容不会被占用。实际使用的std中只有coutendl两个名称,因此编译代码的最终结果是相同的。

优点和缺点是:

  • 在大多数行中,这一行将有更简洁的代码。读过这本书的人可能不得不更仔细地考虑一下coutendl的定义,尽管这并不是他们所熟知的问题。编译可能需要更长的时间,因为每个名称的可能含义范围都稍大一些,但这可能忽略不计,除非程序很大,并且您正在编译的机器非常弱。如果作用域中的其他命名空间定义了coutendl,那么名称将不明确,您将被迫使用其他名称之一。

  • 数字1的优点,只引入两个名字就减少了缺点。

  • 与第一个相反。无论是编译器还是开发人员,在查看源代码时都没有含糊不清的地方,但代价是要更加详细。

  • 因此,如果这是整个文件中std的唯一用途,那么使用方法3可能是值得的;如果std中有很多重复使用的东西,那么使用方法1(8)和endl可能是第一;如果大量使用coutendl,那么使用方法2可能是值得的,但std中没有其他方法。

    或者你可以一直使用数字1,除非被一个歧义所强迫去做其他的事情。

    这两者并非互相排斥。一个人可以做到:

    1
    2
    3
    using namespace std;
    /*...*/
    std::cout <<"Hello" << std::endl;

    当然,在这里,std::是多余的,但是我们可以这样做,如果上下文中这些内容不明确,但是std的其他用法不明确,或者人们可能不熟悉某个特定的名称,因此冗余代码有助于可读性。还有一些名称,由于它们的全名是这样的,所以更常见的是,这样做本身就有助于提高可读性。

    尽管如此,除非有歧义(无法编译),否则所有这些都会在编译时生成相同的程序。

    编辑:

    我假设这里有一个.cpp文件,但我同意其他人关于头的看法。在一个.h文件中,您强制对它所包含的所有文件做出决定,并且只需要一个文件具有模糊性,就可以将其作为一个错误的调用。对于开发人员来说,它也不太明显,因为包含位置不靠近使用位置。

    如果您真的想在.h文件中使用1或2,那么通过将其放在名称空间、类或函数中来确定using的范围,这样在等待包含该文件的人时就不会有任何意外了。


    我通常更喜欢第三种样式,但有时它更紧凑,使用第一或第二种样式更简单。我有时在本地使用。例如:

    1
    2
    3
    4
    5
    void foo()
    {
        using namespace std;
        //do stuff
    }

    但我宁愿不在模块中全局写入using namespace std