我创建了Tag系统,它允许ma引擎中的标签实体。它基于c ++类型工作,所以每个标签都是一种类型(我有我的理由)。
现在,当我想创建新标记时,我必须调用struct tagname{};
。
如果我想在其他文件中使用标记,我使用前向声明struct name;
为了使用户更友好,我创建了宏
#define CREATE_TAG(name) struct name{};
#define USE_TAG(name) struct name;
但是当用户在命名空间和其他外部命名空间中调用一个宏时,我遇到了问题,因为这是两种不同的类型。
我想确保用户在任何命名空间之外调用宏。由于我们的项目位于一个名称空间namespace root
中,因此我可以将其用于chcecking。
这是我到目前为止所提出的:
namespace root
{
const unsigned TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE = 1;
};
#define CREATE_TAG(name) namespace root{ struct name{}; static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,""); }
#define USE_TAG(name) namespace root{ struct name; static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,""); }
现在当在根命名空间之外使用宏时,一切都很好。在根命名空间或其他嵌套命名空间内调用时,它会给出错误TAGS_CAN_BE... not a member
。
但我真的不喜欢它。我不喜欢整个宏观事物,但这不是问题。问题是:如果在命名空间中调用宏,是否有更好的方法可以找到? 由于我的宏传入Type,我可以使用一些类型特征,但我找不到任何合适的特征。
答案 0 :(得分:0)
您可以尝试这样的事情:
#include <type_traits>
#define DECLARE_ME(name) struct tag_##name { static_assert(!std::is_same<tag_##name, ::tag_##name>::value, "Not in global namespace"); }
你可能会遇到一个编译器错误,即使在滥用的情况下也不是静态断言,但它应该能够解决问题。你可以通过一个更精细的特质类使它更加用户友好。
答案 1 :(得分:0)
所以看起来
namespace root
{
const unsigned TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE = 1;
};
#define CREATE_TAG(name) namespace root{ struct name{}; static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,""); }
#define USE_TAG(name) namespace root{ struct name; static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,""); }
是答案......
在我接受之前,我会等几天。我仍然对你的答案持开放态度