There seem to be different views on using 'using' with respect to the std namespace.
Some say use ' using namespace std
', other say don't but rather prefix std functions that are to be used with ' std::
' whilst others say use something like this:
using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::vector;
for all the std functions that are to be used.
What are the pros and cons of each?
First, some terminology:
using std::vector;
using namespace std;
I think that using using-directives are fine, as long as they aren't used at the global scope in a header file. So having
in your .cpp file isn't really a problem, and if it turns out to be, it's completely under your control (and it can even be scoped to particular blocks if desired). I see no particlar reason to clutter up the code with a slew of
std::
qualifiers - it just becomes a bunch of visual noise. However, if you're not using a whole bunch of names from thestd
namespace in your code, I also see no problem with leaving out the directive. It's a tautology - if the directive isn't necessary, then there's no need to use it.Similarly, if you can get by with a few using-declarations (instead of using-directives) for specfic types in the
std
namespace, then there's no reason you shouldn't have just those spefcific names brought into the current namespace. By the same token, I think it would be crazy and a bookkeeping hassle to have 25 or 30 using-declarations when a single using-directive would do the trick just as well.It's also good to keep in mind that there are times when you must use a using-declaration. Refer to Scott Meyers' "Item 25: Consider support for a non-throwing swap" from Effective C++, Third Edition. In order to have a generic, templated function use the 'best' swap method for a parameterized type, you need to make use of a using-declaration and argument dependant lookup (aka ADL or Koenig lookup):
I think we should look at the common idioms for various languages that make significant use of namespaces. For example, Java and C# use namespaces to a large extent (arguably moreso than C++). The most common way names within namespaces are used in those languages is by bringing them into the current scope en masse with the equivalent of a using-directive. This doesn't cause wide-spread problems, and the few times it is a problem are handled on an 'exception' basis by dealing with the names in question via fully-qualified names or by aliasing - just like can be done in C++.
Herb Sutter and Andrei Alexandrescu have this to say in "Item 59: Don't write namespace usings in a header file or before an #include" of their book, C++ Coding Standards: 101 Rules, Guidelines, and Best Practices:
Stroupstrup is often quoted as saying, "Don’t pollute the global namespace", in "The C++ Programming Language, Third Edition". He does in fact say that (C.14[15]), but refers to chapter C.10.1 where he says:
And how does one have the same advantage as a 'lazy user of global names'? By taking advantage of the using-directive, which safely makes names in a namespace available to the current scope.
Note that there's a distinction - names in the
std
namespace made available to a scope with the proper use of a using-directive (by placing the directive after the#includes
) does not pollute the global namespace. It's just making those names available easily, and with continued protection against clashes.For me, I prefer to use
::
when possible.I hate to write :
Hopefully, with C++0x I would write this:
If the namespace is very lengthy,
Most C++ users are quite happy reading
std::string
,std::vector
, etc. In fact, seeing a rawvector
makes me wonder if this is thestd::vector
or a different user-definedvector
.I am always against using
using namespace std;
. It imports all sorts of names into the global namespace and can cause all sorts of non-obvious ambiguities.Here are some common identifiers that are in the
std
namespace: count, sort, find, equal, reverse. Having a local variable calledcount
means thatusing namespace std
won't enable you to usecount
instead ofstd::count
.The classic example of an unwanted name conflict is something like the following. Imagine that you are a beginner and don't know about
std::count
. Imagine that you are either using something else in<algorithm>
or it's been pulled in by a seemingly unrelated header.The error is typically long and unfriendly because
std::count
is a template with some long nested types.This is OK though, because
std::count
goes into the global namespace and the function count hides it.Perhaps slightly surprisingly, this is OK. Identifiers imported into a declarative scope appear in the common namespace that encloses both where they are defined and where they are imported into. In other words,
std::count
is visible ascount
in the global namespace, but only insideincrement
.And for similar reasons,
count
is ambiguous here.using namespace std
doesn't causestd::count
, hide the outercount
as it might be expected. Theusing namespace
rule means thatstd::count
looks (in theincrement
function) as though it was declared at the global scope, i.e. at the same scope asint count = 0;
and hence causing the ambiguity.Namespaces keep code contained to prevent confusion and pollution of function signatures.
Here's a complete and documented demo of proper namespace usage:
Output:
There are several ways to fix that.
First: use like what you did.
Second: do
namespace S = std;
, reducing 2 chars.Third: use
static
.Fourth: don't use names that
std
uses.You should never be
using namespace std
at namespace scope in a header. Also, I suppose most programmers will wonder when they seevector
orstring
withoutstd::
, so I think notusing namespace std
is better. Therefor I argue for never beusing namespace std
at all.If you feel like you must, add local using declarations like
using std::vector
. But ask yourself: What's this worth? A line of code is written once (maybe twice), but it's read ten, hundred or thousand times. The saved typing effort be adding a using declaration or directive is marginal compared to the effort of reading the code.With that in mind, in a project ten years ago we decided to explicitly qualify all identifiers with their full namespace names. What seemed awkward at first became routine within two weeks. Now, in all projects of that whole company nobody is using using directives or declarations anymore. (With one exception, see below.) Looking at the code (several MLoC) after ten years, I feel like we made the right decision.
I've found that usually, those who oppose banning
using
usually haven't tried it for one project. Those who have tried, often find it better than using directives/declarations after a very short time.Note: The only exception is
using std::swap
which is necessary (especially in generic code) to pick up overloads ofswap()
that cannot be put into thestd
namespace (because we aren't allowed to put put overloads ofstd
functions into this namespace).