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.
Consider this program:
line#
1 #include <string>
2
3 using namespace std;
4
5 struct string { const char* p; }; // Beware: another string!
6
7 int main()
8 {
9 string x; // Error: ambiguous - which string is wanted?
10 }
If you try to compile it, you'll see errors:
g++ using.cc -o using
using.cc: In function `int main()':
using.cc:9: error: use of `string' is ambiguous
using.cc:5: error: first declared as `struct string' here
/usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stringfwd.h:60: error:
also declared as `typedef struct std::basic_string<char, std::char_traits<char>, std::allocator<char> > std::string' here
using.cc:9: error: `string' was not declared in this scope
using.cc:9: error: expected `;' before "x"
The problem here is that when main()
specifies string x;
, the compiler's not sure whether the user-defined ::string
or included std::string
is wanted.
Now imagine you take the top part of the program... lines 1 through 5 - up to and including the struct string
... and put it into a header file which you then #include
before main()
. Nothing changes: you still have an error. So, just as for standalone programs, header files with using
statements in them can cause trouble for other code that includes them, making some of their statements ambiguous.
It can be a bigger pain though, as headers can be included - directly or indirectly - by arbitrarily huge amounts of dependent code, and...
- removing the
using
statement from the header, or
- a change to the contents of
<string>
, or any other header affecting std::
...might break code including the problematic header. Either problem may render dependent code uncompilable, and issues may not even be noticed until another compilation is attempted. Further, the person suffering due to the using
statement may not have filesystem/code-repository permissions, corporate authority etc. to remove the using
statement from the header, nor fix other affected client code.
That said, if a header only has "using" inside a class or function, then there's no affect on code beyond that scope, so the potential impact of changes to std:: is dramatically reduced.
Best Answer
Consider two libraries called Foo and Bar:
Everything works fine, and you can call
Blah()
from Foo andQuux()
from Bar without problems. But one day you upgrade to a new version of Foo 2.0, which now offers a function calledQuux()
. Now you've got a conflict: Both Foo 2.0 and Bar importQuux()
into your global namespace. This is going to take some effort to fix, especially if the function parameters happen to match.If you had used
foo::Blah()
andbar::Quux()
, then the introduction offoo::Quux()
would have been a non-event.