HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Solving the problem of using directives in a header file with a macro. Is this stupid?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thisproblemsolvingtheheaderfilewithstupidusingmacro

Problem

I am writing some library code that is mostly templates and so is all contained in header files. I know that placing a using declaration in a header will pollute all the files that include it, but I'm also starting to be really annoyed by having to spell out all the namespaces..
After a bit of tinkering I came up with these macros:

#define MACRO_CONCAT_IMPL( x, y ) x##y
#define MACRO_CONCAT( x, y ) MACRO_CONCAT_IMPL( x, y )

#define PRIVATE_NAMESPACE_IMPL( name ) namespace name { namespace exports{} } using namespace name::exports; namespace name {

#define PRIVATE_NAMESPACE PRIVATE_NAMESPACE_IMPL(MACRO_CONCAT(private_namespace_,__COUNTER__))
#define END_PRIVATE_NAMESPACE }

#define PUBLIC_SECTION namespace exports{
#define END_PUBLIC_SECTION }


To be used like this:

namespace MyNamespace{

PRIVATE_NAMESPACE

    using namespace std;
    using namespace ThirdParty::Library;
    using namespace MyCompany::OtherProduct;

PUBLIC_SECTION

    class Class{
        wstring GetString();
    };
END_PUBLIC_SECTION

END_PRIVATE_NAMESPACE

}


This will create a private namespace with the using declarations and a nested one with the publicly available code that is then imported into the topmost namespace (MyNamespace).

This is different from a plain nested namespace as it expands into this:

namespace MyNamespace{
    namespace private_namespace_0{

      using namespace std;
      using namespace ThirdParty::Library;
      using namespace MyCompany::OtherProduct;

      namespace exports{
            class Class{
                wstring GetString();
            };
        }
    }
    using namespace private_namespace_0::exports;
}


This way the "public" section has access to the "private" one and only the public one is accessible with MyNamespace::.
The weird thing with the counter is to ensure each header has its own private namespace so that declarations are not shared between separate header files. Giving an ID to the namespaces is also the onl

Solution

You're writing a lot of code, but what is the benefit? How is this any worse?

namespace MyNamespace {
    namespace ImplDetails {
        // Non-public code.
    }
    // Public code.
}


Yes, people can access things in ImplDetails, but you can't get around that sanely. Obscuring namespace names is only going to hurt compatibility (when a namespace gets renamed after you insert a new one, which will happen eventually). If people want to access your internals, they will.

Code Snippets

namespace MyNamespace {
    namespace ImplDetails {
        // Non-public code.
    }
    // Public code.
}

Context

StackExchange Code Review Q#8847, answer score: 5

Revisions (0)

No revisions yet.