С++ Идиоматические черты характера
У меня есть система признаков типа, которая находится в пространстве имен, например:
namespace my_namespace
{
template <typename T>
struct magic_traits
{
static const int value = 0;
};
}
Поскольку люди ненавидят синтаксис специализированных шаблонов, у меня есть этот удобный маленький макрос:
#define DECLARE_MY_MAGIC_TRAITS(type_, value_) \
namespace my_namespace \
{ \
template <> \
struct magic_traits<type_ > { \
static const int value = value_; \
}; \
}
}
Моя проблема в том, что это работает только для объявлений, сделанных в глобальном пространстве имен, поэтому черты для типа в другом пространстве имен выглядят следующим образом:
DECLARE_MAGIC_TRAITS(other_namespace::some_type, 9)
Хорошо, если люди знают обо всех правилах пространства имен, где находится DECLARE_MAGIC_TRAITS
. Если они этого не делают и помещают декларацию в собственное пространство имен, они получат такие ошибки, как:
'magic_traits' is not a template!
Specialization of non-template 'other_namespace::my_namespace::magic_traits'
Это довольно запутанно для нового пользователя вашей библиотеки!
Есть ли способ сделать этот макрос способным определить специализацию magic_traits
из любого места? Если это невозможно (как я подозреваю): Какие методы могут быть использованы для генерации более разумных сообщений об ошибках?
Я должен отметить, что мои пользователи в основном являются программистами на Python и имеют очень мало опыта на С++, поэтому все, что я могу сделать, чтобы сделать их жизнь проще, тем лучше.
Ответы
Ответ 1
Может быть, немного уродливо, но как насчет идеи:
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_; \
}; \
}
Когда макрос используется неправильно, он генерирует ошибку, такую как:
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’
Это может дать достаточно намека на то, что неправильно.
Ответ 2
Нет ничего лучше хорошей документации.
Вы должны сообщить пользователям своего макроса DECLARE_MAGIC_TRAITS, куда поместить макрос, и что писать внутри параметров (с примерами)
И сделайте сообщения об ошибках записью faq, чтобы пользователи нашли хороший ответ на то, что пошло не так.