I have a system of type traits that resides in a namespace, like so:
namespace my_namespace
{
template <typename T>
struct magic_traits
{
static const int value = 0;
};
}
Because people hate the syntax of template specializations, I have this convenient little macro:
#define DECLARE_MY_MAGIC_TRAITS(type_, value_) \
namespace my_namespace \
{ \
template <> \
struct magic_traits<type_ > { \
static const int value = value_; \
}; \
}
}
My problem is that this only works for declarations made in the global namespace, so traits for a type in some other namespace looks like this:
DECLARE_MAGIC_TRAITS(other_namespace::some_type, 9)
That's great, if people know about all the little namespace rules about where DECLARE_MAGIC_TRAITS
belongs. If they don't and put the declaration in their own namespace, they'll get errors like:
'magic_traits' is not a template!
Specialization of non-template 'other_namespace::my_namespace::magic_traits'
Which are quite confusing to a new user of your library!
Is there a way to make that macro be able to define a specialization of magic_traits
f开发者_运维技巧rom anywhere? If that is not possible (as I suspect): What techniques can be used to generate more reasonable error messages?
I should note that my users are mostly Python programmers and have very little C++ experience, so anything I can do to make their lives easier, the better.
Maybe a bit ugly, but how about this as an idea :
namespace my_namespace
{
typedef bool The_DECLARE_MY_MAGIC_TRAITS_macro_should_be_used_in_the_global_namespace;
template <typename T>
struct magic_traits
{
static const int value = 0;
};
}
#define DECLARE_MY_MAGIC_TRAITS(type_, value_) \
namespace my_namespace { \
typedef The_DECLARE_MY_MAGIC_TRAITS_macro_should_be_used_in_the_global_namespace CheckPrecondition; \
template <> \
struct magic_traits<type_ > { \
static const int value = value_; \
}; \
}
When the macro is used incorrectly, it would generate an error such as this :
error: ‘The_DECLARE_MY_MAGIC_TRAITS_macro_should_be_used_in_the_global_namespace’ does not name a type
error: ‘magic_traits’ is not a template
error: explicit specialization of non-template ‘other_namespace::my_namespace::magic_traits’
That might give enough of a hint as to what's wrong.
There is probaly nothing better than good documentation.
You should tell the users of your DECLARE_MAGIC_TRAITS macro where to put the macro, and what to write inside the parameters (with examples)
And make the error messages a faq entry so that users will find a good answer to what went wrong.
精彩评论