Using std Namespace

2018-12-31 07:21发布

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?

15条回答
看风景的人
2楼-- · 2018-12-31 07:56

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 code PrefixNS::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

typedef struct list {} list;

We had to integrate and adapt some code (which I'll name "engine") which looked like this:

#include <list>
...
using std::list;
...
void foo(list const&) {}

So we modified like this:

#include <list>

#include "module.h"
...
using std::list;
...
void foo(list const&) {}

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.

查看更多
路过你的时光
3楼-- · 2018-12-31 07:57

Both

using std::string;

and

using namespace std;

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.

查看更多
春风洒进眼中
4楼-- · 2018-12-31 08:00

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 the BuzFlox::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 and while's and continue'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.

查看更多
登录 后发表回答