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 only reason that i'm using macros.
Using a "private" namespace seems to be accepted practice as boost does it too. I also know that __COUNTER__
isn't really portable but vc++ and gcc both support it..
Is there anything really wrong with this idea or a better/standard way to do it?