patterncppMinor
Solving the problem of using directives in a header file with a macro. Is this stupid?
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:
To be used like this:
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:
This way the "public" section has access to the "private" one and only the public one is accessible with
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
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?
Yes, people can access things in
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.