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:
开发者_JAVA技巧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.
So, why do people always say std:: instead of ::std::
Probably because they never really had problems with ambiguity because of it.
Along the same lines: I never had to include "earth" in my address, and I'm not going to.
You have to draw the line somewhere, and this it is a reasonable assumption that others won't make their own std namespaces, or at least that a library that does won't be very popular. :)
The practical reason for unanchored namespaces is that one level of namespaces usually is enough. When it isn't, a second level is usually going to be used for implementation details. And finally, even when using multiple levels, they are still usually specified implicitly from root level. ie. even inside namespace ns1
, you'd typically refer to ns1::ns2::foo
instead of ns2::foo
or ::ns1::ns2::foo
.
So, for these three reasons the ::ns1
form is redundant in normal cases. The only case where I'd consider it would be in submissions to Boost, because as a Boost author I won't know where my software will be used.
why do people always say std::
Not always. I use string
and using ::std::string
. So nothing bad if there will be fred::std::string
, because I still use std::string
. In small cpp-files it could be even using namespace ::std
. Sample:
#include <iostream>
using ::std::string;
//using namespace ::std; // good for small cpp-files
int main()
{
string s = "sometext"; // no leading ::std
}
you should just never name a namespace std
Yes, you shouldn't give a name std
to custom namespace.
Okay, you say that std
is only an example. But to me it appears your question is only applicable to a case where somebody does something as evil as overriding std
.
Let me provide another example:
namespace logging
{
// Logs to local file
}
namespace server
{
namespace logging
{
// Logs to remote destination
}
}
namespace client
{
namespace logging
{
// Logs to local file and to screen
}
}
In this case, not prepending ::
results in default behavior.
This is so much artificial:
namespace fred {
namespace std { // A standard fred component
class string { // Something rather unlike the ::std::string
// ...
};
} // namespace std
} // namespace fred
This Fred would not be able to explain why he did that to the whole team.
To answer your question: people omit first "::" because it is a habit, which saves time and because it is easier to expect that when namespace is used anywhere, then such name is absolute, not relative.
In the case of std
I wouldn't assume any other namespace with the same name, same classes but different meaning.
In other cases, the leading ::
just looks ugly, and makes reading code more difficult (in my opinion). Namespace clashes are too rare to put the ::
in front of everything.
A lot of code is written in the global namespace. If someone really redefines ::std::, it won't matter how you refer to it in that kind of code.
Also, your scenario is both unlikely and easy to work around. Firstly, the convention since there was a 'std' was that you don't use that name. Secondly, if you were to encounter a package that defined the 'std' namespace, you just do this:
#include <package_name.hpp>
namespace package_name {
using namespace std;
}
namespace my_app {
class my_class : public package_name::class_of_something {};
}
Or something similar. You might have to explicitly name ::std as std. My point is this: people go about using the un-anchored 'std::' all the time because even the worst-case consequences aren't a big deal, and unlikely at that.
In the same way that names prefixed with _
are reserved, consider std::
as good as reserved.
精彩评论