using namespace std; in a header file

女生的网名这么多〃 提交于 2019-11-26 17:51:10

Let's say I declare a class string myself. Because I'm a lazy bum, I do so in global namespace.

// Solar's stuff
class string
{
    public:
        string();
        // ...
};

Some time later on, I realize that re-using some of your code would benefit my project. Thanks to you making it Open Source, I can do so:

#include <solarstuff.hpp>
#include <phoenixstuff.hpp>

string foo;

But suddenly the compiler doesn't like me anymore. Because there is a ::string (my class) and another ::string (the standard one, included by your header and brought into global namespace with using namespace std;), there's all kinds of pain to be had.

Worse, this problem gets promoted through every file that includes my header (which includes your header, which... you get the idea.)

Yes I know, in this example I am also to blame for not protecting my own classes in my own namespace, but that's the one I came up with ad-hoc.

Namespaces are there to avoid clashes of identifiers. Your header not only introduces MyStuff into the global namespace, but also every identifier from string and fstream. Chances are most of them are never actually needed by either of us, so why dragging them into global, polluting the environment?

Addition: From the view of a maintenance coder / debugger, foo::MyStuff is ten times more convenient than MyStuff, namespace'd somewhere else (probably not even the same source file), because you get the namespace information right there at the point in the code where you need it.

Karthik T

Multiple instances of using namespace std; will not cause any ambiguity. The problem is that that statement imports all the names/types/functions of std into your namespace, and now if you want to name a class string for instance, you will hit into trouble. This is more likely to happen with functions like remove, erase, etc.

The use of it in headers is one level worse because that propagates to all the .cpps that header, without the awareness of person including it. Using it in .cpp atleast needs a conscious choice.

A more complete explanation can be got at Why is "using namespace std" considered bad practice?

An example of issues that might result from this can be found in How to use an iterator? where the OP defines a function distance, and keeps getting the wrong answer. Another example at Confusion about pointers and references in C++

Namespace usings are for your convenience, not for you to inflict on others: Never write a using declaration or a using directive before an #include directive.

Corollary: In header files, don't write namespace-level using directives or using declarations; instead, explicitly namespace-qualify all names. (The second rule follows from the first, because headers can never know what other header #includes might appear after them.)

I generally understand that being clear is a "good" thing to do, I am however a little unclear on the specificity of how, and I'm most interested in the deeper "why" that underlies it all.

Below code snippets reflects why use using namespace in header file is bad:

// snippet 1
namespace A {
 int f(double);
}

// snippet 2
namespace B {  
    using A::f;
    void g();
}

// snippet 3
namespace A {
    int f(int);
}

// snippet 4
void B::g() {
    f(1);   // which overload is called?
}

So in your example, simply this one is better:

#include <string>

class MyStuff
{
    std::string name;
};

Recommend book: C++ Coding Standards: 101 Rules, Guidelines, and Best Practices

and link: Google C++ coding guide

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!