tags:

views:

235

answers:

4

If you use nested namespaces, declarations in header files can get very long and unreadable.

//header1
namespace test { namespace test1 {
class Test {};
} } //namespace

In header2 of the program:

#include "header1"

namespace test2 {

class Test1 {
  void test(test::test1::Test &test) {}
  void test1(test::test1::Test &test) {}
  void test2(test::test1::Test &test1, test::test1::Test &test2) {}
};

}

Are there any possibilities to shorten the names in header2?

A: 

In file header2.h

using namespace test::test1;
Paul Mitchell
This works, but I suggest avoiding using declarations in header files.
MP24
Which introduces more possibility of name conflicts. I strongly suggest avoiding "using" in headers as a general rule.
David Thornley
+2  A: 

you can alias namespaces, like this:

namespace tt=test::test1;
catwalk
but then would tt be an alias for test::test1 in all the files where header2 is included -> could have named test::test1 tt in the first place
bighil
@bighil: you don't alias the namespace in the header, but in the includer, who knows that the alias is (locally) unique
David Schmitt
The question is being asked about the header file, not the implementation file. So this technique is a bad idea.
Omnifarious
+1  A: 

There are ways to shorten the names by using aliases or the using keyword, but they're almost always a bad idea. Namespaces exist for a reason, that reason is to keep things separated. As soon as you put the using keyword in a header file you break that separation, and there's no point in using namespaces at all. Inside your cpp files you can feel free to have using namespace test1 if you're implementing stuff in test1, but I would recomend you not do that in your header file as it is the same as putting it at the top of every single cpp file in which that header is included.

What you have to remember is that declaring something in a header is the same as declaring it in every cpp file in which that header is included. It would also be worth asking yourself, "If you're using test1 inside test2 so often, why are they different namespaces?"

Jason E
+4  A: 

Here is my favorite technique:

#include "header1"

namespace test2 {

class Test1 {
 private:
  typedef ::test::test1::Test MeaningfulName;

  void test(MeaningfulName &test) {}
  void test1(MeaningfulName &test) {}
  void test2(MeaningfulName &test1, MeaningfulName &test2) {}
};

}

I make my typedef aliases private, but I put them right at the beginning of the class declaration. It doesn't matter that they're private to the rest of the program because nobody will be using the aliased name, they will be using the actual type name or their own alias for the name.

I also really prefer to use anchored namespace names to avoid later surprises. My rule for this is that I always use an anchored name unless the namespace is one I control and/or is part of the current project or package or whatever. Then I will use the shortest possible relative name. If that relative name would start from the root namespace, I still often use an anchored name.

The main problem is the digraph <: which will crop up in template declarations a lot once you start using anchored names more often. You have to put in a space to avoid it, especially since digraph processing happens at a really early stage and can give you some very weird error messages.

Omnifarious