What's the purpose of: “using namespace”?

2020-06-08 03:32发布

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?

6条回答
来,给爷笑一个
2楼-- · 2020-06-08 03:42

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.

查看更多
smile是对你的礼貌
3楼-- · 2020-06-08 03:45

"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/

查看更多
男人必须洒脱
4楼-- · 2020-06-08 03:57

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.

查看更多
Explosion°爆炸
5楼-- · 2020-06-08 04:06

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.

查看更多
家丑人穷心不美
6楼-- · 2020-06-08 04:07

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`
}
查看更多
一纸荒年 Trace。
7楼-- · 2020-06-08 04:09

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 ...
查看更多
登录 后发表回答