5

I'm a bit confused concerning proper usage of C++ namespaces. It is clear for me how they can help to avoid conflicts (name collision), but it is not clear anymore when it comes to the using keyword. I mean, suppose I have a part of my code that I put into a namespace, and create a class, say

namespace my
{
    class vector { ... };
}

Of course, when I use it, I wouldn't like to type my::vector all the time, so I'd like using namespace my. However, I could eventually need something from the std namespace, and then I want using namespace std at the same time, but this will bring me back to the initial name collision problem.

I know that it is possible to "import" only the functionality that I need, like using std::set, but in this case it seems natural to import both the standard namespace std and my namespace completely as I'd use both of them all the time.

Does this mean that even when I use namespaces I should still think about giving non-common names to my types? Or is using namespace a mistake and I should always type my::vector instead? Thanks.


Well, I should probably clarify that it is more a question of readability than typing. Lots of :: everywhere look really weird to me. I know it's a question of taste and habits, but nevertheless.

Roman L
  • 2,896
  • 22
  • 37
  • 7
    "I wouldn't like to type `my::vector` all the time" Why not? Fully qualifying names (or using namespace aliases for long namespace names) helps to make your code clearer (there's no guessing where names are coming from). It also helps you to avoid pernicious name lookup issues that can occur when you use a using directive (especially `using namespace std;`). Such name lookup issues don't occur _frequently_, but when they do occur they can be difficult to diagnose, and I've answered more than a few hard questions on Stack Overflow about problems that resulted from a `using namespace std;`. – James McNellis Feb 22 '11 at 15:43
  • 1
    @James: The main motivation is not that much about typing, but more about readability. Probably it is a question of taste and habits, but at the moment lots of `::` everywhere really make it more difficult to read to me. – Roman L Feb 22 '11 at 15:50
  • @James: And it gets even worse in the case of nested namespaces, `my::db::helpers::class` (random example, please don't take it too serious) looks really awful to me :) – Roman L Feb 22 '11 at 15:53
  • 4
    @7vies: the problem in your last comment can be solved with `namespace dbhelp = my::db::helpers;` – Fred Foo Feb 22 '11 at 15:58
  • 3
    @7vies: It's still easier (because of namespace aliases and using declarations/directives) than my_db_helpers_class, which is what you get in manageable code without namespaces. That said, I often wish you could use periods instead of double colon there. – Fred Nurk Feb 22 '11 at 15:58
  • @7vies: yes, it does. See James' comment to my answer. When necessary, use a `using` directive at function scope. – André Caron Feb 22 '11 at 15:59
  • @larsmans: nice one, I was almost forgetting about namespace aliases! – André Caron Feb 22 '11 at 15:59
  • @AndréCaron: You can even use namespace aliases at function scope. – Fred Nurk Feb 22 '11 at 16:01
  • @larsmans: wow, how could I've missed this feature?? Thanks for pointing it out! – Roman L Feb 22 '11 at 16:01
  • For those using older versions of C++ compilers, type alias can be mimicked with [`typedef` (en.cppreference.com)](http://en.cppreference.com/w/cpp/language/typedef). It works similar to namespace alias, except that before C++11 one can only `typedef` one type at a time, and if it is a template then the template arguments need to be specified. – rwong Aug 16 '15 at 01:50

3 Answers3

10

Of course, when I use it, I wouldn't like to type my::vector all the time, so I'd like using namespace my. However, I could eventually need something from the std namespace, and then I want using namespace std at the same time, but this will bring me back to the initial name collision problem.

Yes, it would bring you back to the initial name collision problem. This is why you should use using namespace ...; directives sparingly, and only in source files, never in headers.

Does this mean that even when I use namespaces I should still think about giving non-common names to my types?

No, you shouldn't. Namespaces were invented precisely to avoid this.

Or is using namespace a mistake and I should always type my::vector instead?

You can, if you want to, use the using namespace ...; or using ...; directives until you get conflicts. This means that when you do have conflicts, you'll end up writing "unnatural" code by explicitly quallifying names in some places.

In practice, when you're dealing with short namespace names (i.e. std), you can just type them explicitly all the time. After a week or so, you won't even notice you're typing it anymore.

André Caron
  • 41,491
  • 10
  • 58
  • 117
  • 5
    Ideally, if a using directive is to be used, it should be used at function scope, which makes it easy to keep track of. – James McNellis Feb 22 '11 at 15:53
  • 2
    +1 for "you won't even notice you're typing it anymore." I've quit putting `using namespace` at file scope and rarely type `using` directives at all (only for standard types that pop up throughout a module or function). – Fred Foo Feb 22 '11 at 15:54
  • @James: I also resort to that for painfully long namespaces, indeed! – André Caron Feb 22 '11 at 15:57
4

If your code uses both std::vector and my::vector, then always writing the names in full is the best option.

Fred Foo
  • 328,932
  • 68
  • 689
  • 800
0

Why bother putting it in a namespace in the first place, if you are immediately opening up the namespace again? You could just as well have put the class in the global namespace!

It would also be very confusing for people who didn't notice the using directive at the top of your file, that vector isn't std::vector. That in itself is a reason for writing my::vector!

To me, seeing names like std::vector and std::list actually improves readability, because I immediately know what those names mean.

Bo Persson
  • 86,087
  • 31
  • 138
  • 198
  • 1
    Of course I'm not opening it up again everywhere, mostly in the .cpp files where the classes from those namespaces are heavily used, so it is not exactly the same as making them global. I still disagree on `::`, as I find them visually distracting too much. I actually agree to @Fred Nurk that ability to use periods in place of colons (like in Java/Python/C#) would be very helpful. – Roman L Feb 22 '11 at 17:40