问题
There are convincing arguments against using namespace std
, so why was it introduced into the language at all? Doesn't using namespace
defeat the purpose of namespaces? Why would I ever want to write using namespace
? Is there any problem I am not aware of that is solved elegantly by using namespace
, maybe in the lines of the using std::swap
idiom or something like that?
回答1:
For one thing, this is the way to use operator overloads in a namespace (e.g using namespace std::rel_ops;
or using namespace boost::assign;
)
Brevity is also a strong argument. Would you really enjoy typing and reading std::placeholders::_1
instead of _1
? Also, when you write code in functional style, you'll be using a myriad of objects in std
and boost
namespace.
Another important usage (although normally one doesn't import whole namespaces) is to enable argument-dependent look-up:
template <class T>
void smart_swap(T& a, T& b)
{
using std::swap;
swap(a, b);
}
If swap is overloaded for some type of T in the same namespace as T, this will use that overload. If you explicitly called std::swap
instead, that overload would not be considered. For other types this falls back to std::swap
.
BTW, a using declaration/directive does not defeat the purpose of namespaces, since you can always fully qualify the name in case of ambiguity.
回答2:
Most of the times it is just a shortcut for writing code. You can import names into your enclosing context. I usually restrict it to .cpp
files, because when you include an using directive into a .h
file, it pollutes all the files in which it is included. Another good practice is restricting the using namespace
to the most enclosing environment possible, for instance, inside of a method body declaration. I see it as a convenience, no more, and similar to namespace aliasing, such as:
namespace po = boost::program_options;
and then you can write
po::variables_map ...
回答3:
The main reason why using namespace
was introduced was backwards compatibility: If you have lots of pre-namespace code using lots of (pre-standard versions of) standard library functions and classes, you want a simple way to make that code work with a standard conforming compiler.
BTW, the argument dependent lookup rules at least for C++98 mean that using namespace std::rel_ops
will not do what you want in templates (I don't know if this changed in a later version of the standard).
Example:
template<typename T> bool bar(T t)
{
return t > T();
}
namespace foo
{
class X {};
bool operator<(X, X);
}
using namespace std::rel_ops;
int main()
{
X x;
bar(x); // won't work: X does not have operator>
}
Note that putting the using namespace
in namespace foo
won't help either.
However, using declarations in the right spot help:
template<typename T> bool bar(T t)
{
return t > T();
}
namespace foo
{
class X {};
bool operator<(X, X);
using std::rel_ops::operator>;
}
int main()
{
X x;
bar(x); // now works: operator> found per ADL via the using declaration in `namespace foo`
}
回答4:
People specifically object to using namespace std;
but not to using namespace BigCorp
; or to referring to std::cout
(which is using the namespace, just not using
it, if you know what I mean.) Also, most of the objections to using namespace std
are in a header file. In a source file, where the effects can be immediately seen, it's less harmful.
Namespaces are an incredibly useful concept that allow me to have a class called Date even though a library I'm using has a class called Date. Before they were added to the language, we had to have things like GCDate
and GCString
(my company, Gregory Consulting, predates std::string
). Making use of namespaces (with or without the using
keyword) lets us all write cleaner, neater code. But when you have to say Gregcons::string
every time, you kind of lose the cleaner, neater part. [Disclaimer: I don't actually use my own string class anymore - imagine some appropriate name conflict.] That's the appeal of the using
statement. Keep it out of headers, don't apply it to std
, and you should generally stay out of trouble.
回答5:
I find it useful when working with libraries with deeply nested namespaces. The Boost library is one such example. Imaging typing boost::numeric::ublas::matrix<double> m
all over the place ...
The thing to avoid is doing using namespace
in a header file as this has the potential for royally screwing up any program that includes said header. Always place using namespace
statements in .cpp/.cxx files, so that it's restricted to file scope.
回答6:
"Namespaces allow to group entities like classes, objects and functions under a name. This way the global scope can be divided in "sub-scopes", each one with its own name. Where identifier is any valid identifier and entities is the set of classes, objects and functions that are included within the namespace"
More information here: http://www.cplusplus.com/doc/tutorial/namespaces/
来源:https://stackoverflow.com/questions/4359706/whats-the-purpose-of-using-namespace