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?
Never use using namespace at global scope in an header file. That can leads to conflict and the person in charge of the file where the conflict appears has no control on the cause.
In implementation file, the choices are far less well cut.
Putting a using namespace std brings all the symbols from that namespaces. This can be troublesome as nearly no body know all the symbols which are there (so having a policy of no conflict is impossible to apply in practice) without speaking of the symbols which will be added. And the C++ standard allows an header to add symbols from other headers (the C one doesn't allow that). It still can work well in practice to simplify the writing in controlled case. And if an error occur, it is detected in the file which has the problem.
Putting using std::name; has the advantage of simplicity of writing without the risk of importing unknown symbols. The cost is that you have to import explicitly all wanted symbols.
Explicitly qualifying add a little clutter, but I think it is the less trouble some practice.
In my project, I use explicit qualification for all names, I accept using std::name, I fight against using namespace std (we have an lisp interpreter which has his own list type and so conflict is a sure thing).
For other namespaces, you have also to take into account the naming conventions used. I know of a project which use namespace (for versionning) and prefix on names. Doing a
using namespace X
then is nearly without risk and not doing it leads to stupid looking codePrefixNS::pfxMyFunction(...)
.There are some cases where you want to import the symbols. std::swap is the most common case: you import std::swap and then use swap unqualified. Argument dependent lookup will find an adequate swap in the namespace of the type if there is one and fall back to the standard template if there is none.
Edit:
In the comments, Michael Burr wonders if the conflicts occur in real world. Here is a real live exemple. We have an extension language with is a lisp dialect. Our interpreter has an include file, lisp.h containing
We had to integrate and adapt some code (which I'll name "engine") which looked like this:
So we modified like this:
Good. Everything work. Some months later, "module.h" was modified to include "list.h". The tests passed. "module" hadn't be modified in a way that affected its ABI, so "engine" library could be used without re-compiling its users. Integration tests were OK. New "module" published. Next compilation of engine broke when its code hasn't be modified.
Both
and
add some symbols (one or lots of) to the global namespace. And adding symbols to global namespace is something you should never do in header files. You have no control who will include your header, there are lots of headers that include other headers (and headers that include headers that include headers and so on...).
In implementation (.cpp) files it's up to you (only remember to do it after all #include directives). You can break only code in this specific file, so it's easier to manage and find out the reason of name conflict. If you prefer to use std:: (or any other prefix, there can be many namespaces in your project) before indentifiers, it's OK. If you like to add identifiers you use to global namespace, it's OK. If you want to bring whole namespace on your head :-), it's up to you. While the effects are limited to single compilation unit, it's acceptable.
This discussion is going to be alive as long as the IDE you work with is not flexible enough to show or hide the exact information you need.
That is because what you want your code to look like depends on the task at hand.
While creating my source code, I prefer to see exactly which class I'm using: is it
std::string
, or theBuzFlox::Obs::string
class?When designing the control flow, I'm not even interested in the types of the variables, but I want a focus on
if
's andwhile
's andcontinue
's.So this is my advise:
Depending on the audience of your code and the power of your tools, choose the way that either reads easiest, or gives most information.