Search code examples
c++namespaces

Why does everybody use unanchored namespace declarations (i.e. std:: not ::std::)?


It seems to me that using unanchored namespaces is just asking for trouble later when someone puts in a new namespace that happens to have the same name as a root level namespace and mysteriously alters the meaning of a whole lot of programs. So, why do people always say std:: instead of ::std::. Do they really mean to be saying "I want to use whatever std is handy, not the root one."?

Here is an example of what I mean:

In fred/Foo.h:

#include <string>

namespace fred {

class Foo {
 public:
   void aPublicMember(const std::string &s);
};

} // end namespace fred

In fred/Bar.h:

namespace fred {
namespace std {  // A standard fred component

class string { // Something rather unlike the ::std::string
   // ...
};

} // namespace std

class Bar {
 public:
   void aPublicMember(std::string &s);
};

} // namespace fred

In oops.cpp:

#include <string>
#include "fred/Bar.h"
#include "fred/Foo.h"  // Oops, the meaning of Foo is now different.

Is that what people want, or am I missing something?

And maybe you say that you should just never name a namespace std. And that's all well and good, but what about some other root level namespace then? Should any root level namespace anybody ever defines anywhere always be off-limits for a sub-namespace name?

To clarify, I won't consider any answer that tells me std is special because I just used it as an example. I'm talking about a general issue, and I'm using std as a prop to illustrate it, though I do admit it's a rather startling prop.


Solution

  • It seems to me that using unanchored namespaces is just asking for trouble later when someone puts in a new namespace that happens to have the same name as a root level namespace

    Kind of, but if this problem was common in practice, more people would learn to use fully-qualified identifiers (i.e. those starting with ::). It tends to take a pretty big and/or disorganized project for this sort of issue to come up, and even then it's relatively rare (compared to introducing classes and functions) that a new namespace is introduced, much less one with a name conflict. So a lot of people never see this issue. Few people are burned by it, hence few people take steps to avoid it. They're not asking for trouble; they either are unaware of the possibility or don't consider it reasonably likely.

    And sometimes, when someone introduces a change that causes this problem, the response is yelling at / complaining to that person, rather than changing one's own writing habit. Habits are hard to break. Don't assume that something is good just because it seems like everyone is doing it.