1

我创建了标签系统,它允许在 ma 引擎中标记实体。它基于 c++ 类型工作,所以每个标签都是一个类型(我有我的理由)。

现在,当我想创建新标签时,我必须调用struct tagname{};.

如果我想在其他文件中使用标签,我使用前向声明struct name;

为了使其更加用户友好,我创建了宏

#define CREATE_TAG(name) struct name{};
#define USE_TAG(name)    struct name;

但是当用户在命名空间内调用一个宏和在命名空间外调用另一个宏时,我遇到了问题,因为那是两种不同的类型。

我想确保用户在任何命名空间之外调用宏。由于我们的项目在一个命名空间namespace root中,我可以使用它进行检查。

到目前为止,这是我想出的:

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

但我真的不喜欢它。我不喜欢整个宏观的东西,但这不是问题。问题是:是否有更好的方法来找出是否在命名空间中调用了宏?由于我的宏传入类型,我可以使用一些类型特征,但我没有找到任何合适的类型。

4

2 回答 2

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"); }

你可能会得到一个编译器错误,它甚至不是静态断言,以防误用,但它应该能解决问题。您可能可以使用更精细的 trait 类使其更加用户友好。

于 2012-05-20T10:12:20.573 回答
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,"");  }

是答案...

我会等几天再接受。我仍然愿意接受你的回答

于 2012-05-21T10:18:53.943 回答