c++ - 如果类型是在命名空间内创建的,我如何才能知道?

标签 c++ macros typetraits

我已经创建了标签系统,它允许在 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

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

最佳答案

你可以尝试这样的事情:

#include <type_traits>
#define DECLARE_ME(name) struct tag_##name { static_assert(!std::is_same<tag_##name, ::tag_##name>::value, "Not in global namespace"); }

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

关于c++ - 如果类型是在命名空间内创建的,我如何才能知道?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10672439/

相关文章:

parsing - 如何在 Nimrod 中编译时解析字符串?

scala - 匹配宏中的子类

c++ - 在较新的 Ubuntu 版本中为旧的 Ubuntu 版本编译 C/C++

c++ - Arduino/c++ 在另一个类中使用 SoftwareSerial 类

macros - 术语列表的术语扩展

c++ - 检测类型何时不需要调用其析构函数

c++ - 编译器对编译时分支有什么作用?

C++ 模板,将 enable_if 用于运算符的两种不同实现

c++ - 如何使用 mpicc 和 cmake 更改 c++ 编译器

c++ - Arduino,任务调度程序的延迟