C ++ name resolution

I am interested in a little about namespace and using in C ++, basically I would like to know the differences and figure out how to use it in the best way.

As I can see, there are (at least) three ways to resolve the class name, and I'm not sure how to choose among them:

  • using namespace <namespace>
  • using <namespace>::<what_to_use>
  • <namespace>::<what_to_use> <use_it>

I would like to know the benefits, especially if there is efficiency associated with one way or another, if it is just syntactic and preferred, or if there are other things that I did not consider about this.

+6
source share
5 answers

At first this is using the namespace directive , it brings all the symbol names from the specified namespace to the current namespace, regardless of whether you need / use them. Of course, undesirable.

The second is using a namespace declaration . It enters the specified character name in the current namespace. Advantage - you do not need to type the full name every time.

The third is the full name of the symbol. The disadvantage is that you have to enter the full name wherever you use the character.

It is clear that the second and third are more suitable. In any of them there is no difference in performance. The only difference is the number of characters you enter. Just select either, depending on what your encoding standard indicates.

EDIT:
As @Jerry notes, using an ad in conjunction with an ADL (Argument lookup dependent) can lead to unwanted effects. You can find a detailed explanation in one of my answers:

A detailed explanation of how Koenig search works with namespaces and why is this good?

In chapter,
Why criticism of the Koenig algorithm?

+5
source

There is one (though somewhat unusual) situation in which the form you use can really make a difference, and the form you want to use is using namespace foo , and it most often applies to the std (i.e., where you write using namespace std;

The most obvious example is that you are writing sorting for a custom type. Perhaps this will apply to the type for which the user has also defined his own swap .

You are stuck in a situation where you want to use your swap if they defined it, but use std :: swap if they did not define it. If you use std::swap directly in your code, you end up using std::swap , even if the type has a swap of its own definition. Conversely, your code will not be able to compile if you directly specify swap specifically for this type, and none of them were provided.

To get around this, you do something like:

 using namespace std; template <class Iter> void my_sort(Iter first, Iter last) { // ... if (*last < *first) swap(*first, *last); } 

This will find swap specifically for the type being compared (i.e. a swap defined in the same namespace as this type) if there is one (via an argument-dependent search) and std::swap if none are defined for type (via using namespace std; ).

This can affect performance - if they wrote a swap specifically for their type, you can generally expect this, because by doing this they can provide better performance. This means std::swap explicitly may work, but is likely to result in poor performance.

Otherwise, it is almost entirely a matter of convenience and readability - I prefer to give full names (for example, std::swap ), except for the situation described above, where (at the time I'm writing code) at least two are preferable possibilities, and I want to give the compiler enough freedom to choose the right one.

At the time when I find the use of useful declarations / directives, when the namespace is really heavily nested. Boost (for one obvious example) has some names that would be too long for convenient use if you used the full name every time. This is especially true for the (now, fortunately, mostly obsolete) Boost Lambda library, where you used placeholders like _1 , which would be something like boost::lambda::placeholders::_1 (but I'm going from memory, so which is probably at least partially wrong) if you insisted on using the full name. This, first of all, would do great harm to the purpose of using the lambda library.

+4
source

There is no performance gain or penalty. All calls and variables are resolved at compile time.

The choice between the three is somewhat subjective. Yes, using namespace <ns>; it sometimes frowns on pollution of the global namespace, but I find it safe to use it for small files.

I use the second for testing, where I expect conflicts, but I just delete it later. This can become more messy, because you can end up combining both qualified and unqualified names:

 vector<std::string> x; 

because you have using std::vector; above, but not using std::string; .

I prefer the third.

+2
source

There is a negative effect on the performance of your code, this is pure compilation. This may (theoretically) affect compilation time, but I doubt it will ever reach measurable proportions.

using namespace std (or any other namespace, for that matter) should certainly be avoided in header files that can be included anywhere, and introducing characters into them can lead to ambiguity.

Typically, namespaces exist to avoid name conflicts and using namespace destroys this target. So using the_namespace::some_id , to a lesser extent. There is no definite answer to your question, but I usually follow these rules:

  • Never put using namespace in the header file.
  • Avoid using namespace and using unless it can save a huge amount of input. Use namespace abbrv = some_really::long_and::nested_namespace; if necessary (i.e. namespace abbrv = some_really::long_and::nested_namespace; ).
  • Try limiting the scope to using : you can put this in functions and blocks, as well as in the namespace scope. That is, if you have a logging function in your .cpp file, put using std::cout; and using std::endl; (or whatever you use) in the body of the function, not in the file area.
+1
source

The main reason is that this can lead to ambiguity (both for the compiler and the human reader), and it can also slow down the compilation itself (but this is not such a big problem as the first)

0
source

All Articles