6

I generally like to organize classes I make into modules by using namespaces, and I also don't go more than 2 namespaces deep but it's still painstakingly hard to fully qualify everything.

I've thought of using using directives but I don't want some headers polluting other headers. For example:

MyHeader1.hpp

namespace MyLibrary {
    namespace MyModule1 {
        class MyClass1 {
            // stuff
        };
    } // namespace MyModule1
} // namespace MyLibrary

MyHeader2.hpp

namespace MyLibrary {
    namespace MyModule2 {
        // I can import stuff
        // using namespace MyLibrary::MyModule1;
        // using MyLibrary::MyModule1::MyClass1;

        class MyClass2 {
        public:
            void DoSomething(MyLibrary::MyModule1::MyClass1 parameter); // I could do this
            void DoSomething(MyClass1 parameter); // or this (easier)
        };
    } // namespace MyModule2
} // namespace MyLibrary

MyHeader3.hpp

#include <MyModule2/MyHeader2.hpp>

namespace MyLibrary {
    namespace MyModule2 {
        // I understand that MyClass3 may use MyClass1 from here (the using directive would be beneficial), but what if it doesn't; it's left hanging in here import-ed
        // I can see MyLibrary::MyModule1::MyClass1 from here!

        class MyClass3 {
            MyClass2 some_var;
        };
    } // namespace MyModule 2
} // namespace MyLibrary

The "problem" here is that I can see MyClass1 in MyHeader3.hpp inside the MyModule2 namespace if I import it inside MyHeader2.hpp. I can see that this would not be a problem if using directives were allowed at class scope.

Question is, is there a better way of doing this, should I just man up and fully-qualify everything or should I avoid namespaces altogether?

  • The compilation model of C++ makes this hard without polluting things for your clients as well, but if it's any consolation, you can at least omit the MyLibrary:: part. Modules, when they finally come, should improve this. – Sebastian Redl Feb 9 '16 at 16:15
  • You can use using for type aliases in class scope, and therefore make the alias private. The using namespace … is rarely wise and should be avoided. Applying these two rules avoids imported types in your namespace, and still keeps your code fairly easy to read and write. – amon Feb 9 '16 at 16:22
7

No, you should definetely not abandom namespaces! Instead, you should organize your code better, and maybe check your architecture again.

First, you should not use using namespace MyLibrary::MyModule1; or using MyLibrary::MyModule1::MyClass1; in a header, to avoid namespace polution, since there is no way to undo that (see this question and answers).

Another option is to use typedefs :

namespace MyLibrary {
    namespace MyModule2 {

        class MyClass2 {
        public:

            typedef MyLibrary::MyModule1::MyClass1 FunctionArg;

            void DoSomething(FunctionArg parameter);
        };
    } // namespace MyModule2
} // namespace MyLibrary

And if you use c++11 and later, you can use using in another way :

namespace MyLibrary {
    namespace MyModule2 {

        class MyClass2 {
        public:

            using  FunctionArg=MyLibrary::MyModule1::MyClass1;
            void DoSomething(FunctionArg parameter);
        };
    } // namespace MyModule2
} // namespace MyLibrary
  • Doh! I completely forgot about typedef-ing inside a class. Exactly (kinda) what I needed. Cheers! – John Mark Caguicla Feb 9 '16 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.