7

I'm wondering a bit about the 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 see it there are (at least) three ways to resolve a class name and I am not sure how to choose among them:

  1. using namespace <namespace>
  2. using <namespace>::<what_to_use>
  3. <namespace>::<what_to_use> <use_it>

I would like to know the advantages especially if there are performance involved in one or the other way, if it's just syntactical and a matter of preference or if there are other things I haven't considered regarding this.

Paul Turner
  • 38,949
  • 15
  • 102
  • 166
qrikko
  • 2,483
  • 2
  • 22
  • 35
  • 1
    It is not related to runtime performance. – Alex F Jan 03 '13 at 10:12
  • 1
    I was told when I was in college that, besides having all the namespace in scope, using `using namespace std;` also was a security pitfall. – Adri C.S. Jan 03 '13 at 10:12
  • 1
    1. Is discouraged for the reason you describe 2. Helps you to use functions provided by others in their own namespaces with the help of ADL (see `std::swap`, though let an answer better explain this to you) 3. I prefer most but that is a matter of taste and could be cumbersome if you're not as fond of seeing `std::` all over the place as I am. But none of them has any performance differences, they're just about name resolution and don't get *"compiled into the actual code"*. – Christian Rau Jan 03 '13 at 10:16

5 Answers5

6

First is an using namespace directive, it brings all the symbol names from the specified namespace in your current namespace, irrespective of whether you need/use them. Certainly undesirable.

Second is using namespace declaration. It only brings the specified symbol name in your current namespace. Advantage is you don't have to type the fully qualified name everytime.

Third is an fully qualified names of the symbol. Disadvantage is that you have to type the fully qualified name everywhere you use the symbol.

Clearly, Second & Third are the more suitable ones. There is no performance difference in either of them. The only difference is the amount of characters you type in. Simply, choose either depending on what your coding standard specifies.

EDIT:
As @Jerry points out, using declaration in combination with ADL(Argument dependent lookup) can lead to undesirable effects.
You can find a detailed explanation in one of my answers:

Detailed explanation on how Koenig lookup works with namespaces and why its a good thing?

under the section,
Why the criticism of Koenig Algorithm?

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • I kind of like *using namespace declaration* because I can put it in my .cpp file and I kind of have a list where I see "this is used from these namespaces in this file" but I kind of also like *fully qualified names* as they tell me as soon as I see them that this functionality comes from this namespace. But well I guess I am doing that in some kind of mix and from the answers I've gotten I feel secure to keep at it. Thanks for taking the time to explain this. – qrikko Jan 03 '13 at 10:23
  • 1
    @qrikko: Usually one would go by the coding standards of the organization. Otherwise it is a personal choice.Though important is to have consistency once you make a choice. – Alok Save Jan 03 '13 at 10:26
  • @qrikko: Unfortunately, if you read through my answer, you'll realize that 1) you're not quite as secure as you thought, and 2) all the answers claiming there can't be any effect on performance are (indirectly) at least potentially wrong. They're right that the form in which you specify the name doesn't *directly* affect performance, but still wrong to say (or even imply) that performance can't be effected. – Jerry Coffin Jan 03 '13 at 10:31
5

There is one (admittedly, somewhat uncommon) situation in which the form you use really can make a difference, and the form you want to use is using namespace foo, and it's most commonly applied to the std namespace (i.e., where you write using namespace std;.

The most obvious example is that you're writing a sort for a user-defined type. It's possible that this will be applied to a type for which the user has also defined their own swap.

You're stuck with a situation where you want to use their swap if they've defined one, but use std::swap if they haven't defined one. If you use std::swap directly in your code, then you'll end up using std::swap even if the type has a swap of its own defined. Conversely, your code will fail to compile if you directly specify a swap specifically for the type, and none has been supplied.

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 the swap specifically for the type being compared (i.e., a swap defined in the same namespace as that type), if there is one (via argument dependent lookup), and std::swap if none is defined for the type (via the using namespace std;).

This can have an impact on performance -- if they've written a swap specifically for their type, you can generally expect that it's because by doing so, they can provide better performance. That means that explicitly specifying std::swap may work, but will probably lead to inferior performance.

Otherwise, it's almost entirely a matter of convenience and readability -- I mostly prefer giving the full names (e.g., std::swap) except in a situation like above, where (at the time that I'm writing the code) either of at least two possibilities might be preferred, and I want to give the compiler sufficient leeway to pick the right one.

The other time I find using declarations/directives useful is when namespaces get really deeply nested. Boost (for one obvious example) has some names that would be way too long for convenient use if you used the fully qualified name every time. This was especially true for the (now, thankfully, mostly obsolete) Boost Lambda library, where you used placeholders like _1, that would have ended up as something like boost::lambda::placeholders::_1 (but I'm going from memory, so that's probably at least partly wrong) if you insisted on using a fully qualified name. That would have defeated a large part of the purpose of using the lambda library in the first place.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • there is some valuable information added here I believe. Things to be considered because it actually **do** matter which the choice is in these cases. Thanks for bringing it up. – qrikko Jan 03 '13 at 10:36
  • 2
    I would say, however, that in this case you would prefer to use `using std::swap;` – Andrei Tita Jan 03 '13 at 10:39
2

There's no performance gain or penalty whatsoever. All calls and variables are resolved at compile-time.

The choice between the three is somewhat subjective. Yes, using namespace <ns>; is sometimes frowned upon for polluting the global namespace, but I think it's safe to use for small files.

I tend to use the second one for testing purposes where I'm expecting conflicts, but I'd just remove it afterwards. This can get messier because you can end up with combinations of both qualified and un-qualified names:

vector<std::string> x;

because you have a using std::vector; at the top, but not a using std::string;.

I preffer the third.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
1

There is zero impact on performance of your code, this is purely a compile-time thing. It might (in theory) have some impact on compilation times, but I doubt that would ever reach measurable proportions.

using namespace std (or any other namespace for that matter) is definitely to be avoided in header files, which can be included anywhere and introducing the symbols in them could result in ambiguities.

Generally, namespaces exist to avoid name clashes and using namespace destroys this purpose. So does using the_namespace::some_id, to a lesser degree. There is no definite answer to your question, but I generally follow these rules:

  1. Never put using namespace in a header file.
  2. Avoid using namespace and using, unless it can save tremendous amounts of typing. Use namespace aliases if necessary (that is, namespace abbrv = some_really::long_and::nested_namespace;).
  3. Try to limit the scope of using: you can put this into functions and blocks as well as 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're using) into the function body, not into the file scope.
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
0

Main reason is that it could lead to ambiguities (both for compiler and for human reader) and it can also slowdown the compilation itself (but that's not that big problem as the first thing)

anydot
  • 1,499
  • 9
  • 14