P
Patrik Kahari
A common pattern is to have users register their classes with a
framework. By having users specialize a templated class, located in
the framework namespace, with their user types. To make this easier
for users a macro function is often used. The problem becomes that
users can not use this macro from within any user namespaces. This
makes the macro less useful. Is there a way around this?
<CODE>
namespace LibNs1 {
namespace LibNs2 {
template<typename T>
struct RegsiterClass {};
}
}
//Works but expects to be called from root namespace which is
cumbersome for users
#define REGISTER_CLASS_WITH_LIB_V1(T) \
namespace LibNs1 { \
namespace LibNs2 { \
template<> \
struct RegsiterClass< T > {}; \
}} \
//does not work
#define REGISTER_CLASS_WITH_LIB_V2(T) \
template<> \
struct ::LibNs1::LibNs2::RegsiterClass< T > {}; \
namespace UserNs1 {
namespace UserNs2 {
namespace UserNs3 {
struct UserTypeA {};
REGISTER_CLASS_WITH_LIB_V2(UserTypeA); /* error:
'LibNs1::LibNs2::RegsiterClass<UserNs1::UserNs2::UserNs3::UserTypeA>' :
symbol cannot be defined within namespace 'UserNs3' */
struct UserTypeB {};
REGISTER_CLASS_WITH_LIB_V2(UserTypeB);
struct UserTypeC {};
REGISTER_CLASS_WITH_LIB_V2(UserTypeC);
}}}
//Works but cumbersome for users
REGISTER_CLASS_WITH_LIB_V1(UserNs1::UserNs2::UserNs3::UserTypeA);
REGISTER_CLASS_WITH_LIB_V1(UserNs1::UserNs2::UserNs3::UserTypeB);
REGISTER_CLASS_WITH_LIB_V1(UserNs1::UserNs2::UserNs3::UserTypeC);
</CODE>
For example this issue can be seen with the boost::serialize
BOOST_CLASS_EXPORT macro.
Cheers, Patrik
framework. By having users specialize a templated class, located in
the framework namespace, with their user types. To make this easier
for users a macro function is often used. The problem becomes that
users can not use this macro from within any user namespaces. This
makes the macro less useful. Is there a way around this?
<CODE>
namespace LibNs1 {
namespace LibNs2 {
template<typename T>
struct RegsiterClass {};
}
}
//Works but expects to be called from root namespace which is
cumbersome for users
#define REGISTER_CLASS_WITH_LIB_V1(T) \
namespace LibNs1 { \
namespace LibNs2 { \
template<> \
struct RegsiterClass< T > {}; \
}} \
//does not work
#define REGISTER_CLASS_WITH_LIB_V2(T) \
template<> \
struct ::LibNs1::LibNs2::RegsiterClass< T > {}; \
namespace UserNs1 {
namespace UserNs2 {
namespace UserNs3 {
struct UserTypeA {};
REGISTER_CLASS_WITH_LIB_V2(UserTypeA); /* error:
'LibNs1::LibNs2::RegsiterClass<UserNs1::UserNs2::UserNs3::UserTypeA>' :
symbol cannot be defined within namespace 'UserNs3' */
struct UserTypeB {};
REGISTER_CLASS_WITH_LIB_V2(UserTypeB);
struct UserTypeC {};
REGISTER_CLASS_WITH_LIB_V2(UserTypeC);
}}}
//Works but cumbersome for users
REGISTER_CLASS_WITH_LIB_V1(UserNs1::UserNs2::UserNs3::UserTypeA);
REGISTER_CLASS_WITH_LIB_V1(UserNs1::UserNs2::UserNs3::UserTypeB);
REGISTER_CLASS_WITH_LIB_V1(UserNs1::UserNs2::UserNs3::UserTypeC);
</CODE>
For example this issue can be seen with the boost::serialize
BOOST_CLASS_EXPORT macro.
Cheers, Patrik