【发布时间】:2012-07-02 23:18:44
【问题描述】:
C++ 中是否有一种机制可以用来实现宏,以便宏定义一个类,同时宏的多次调用不会导致类重定义错误?谢谢!
【问题讨论】:
C++ 中是否有一种机制可以用来实现宏,以便宏定义一个类,同时宏的多次调用不会导致类重定义错误?谢谢!
【问题讨论】:
由于宏无法生成任何 C++ 预处理器指令,因此无法在宏的定义中生成 #define 以防止重新生成。您必须以某种方式使用单独的预处理器控件来处理它:
#define CLASS_GENERATOR_MACRO(x, y, z) ...defines class x with attributes y, z...
#ifndef GENERATED_CLASS_A
#define GENERATED_CLASS_A
CLASS_GENERATOR_MACRO(a, int, vector<std::string>);
#endif /* GENERATED_CLASS_A */
但是,没有什么可以自动强制只使用一次CLASS_GENERATOR_MACRO 来创建类a。也就是说,该文件还可以包含:
CLASS_GENERATOR_MACRO(a, double, double);
并且编译器会抱怨类的重新定义(如果两者出现在同一范围内)。
宏可以生成_Pragma 的调用。您的系统提供了一个可以提供帮助的 pragma 的外部机会。但是很可能没有使用 pragma 的可移植解决方案。
【讨论】:
此解决方案假定所需行为是在每次使用宏时实例化一个新类,但名称不同。
可以结合使用__LINE__ macro 和pre-processor token pasting operator ## 在宏实例化期间生成唯一令牌。
#define LOCAL_CLASS(_Base) class _Base ## __LINE__ { /* class definition */ }
然后可以这样使用:
LOCAL_CLASS(SomeBase);
LOCAL_CLASS(SomeBase);
这将生成以下代码(假设宏在源文件的第 2 行和第 3 行实例化:
class SomeBase2 { /* class definition */ };
class SomeBase3 { /* class definition */ };
此解决方案的缺点是生成的类的名称会根据文件中声明的位置而变化,因此不能依赖。如果说该类不打算由宏的用户使用,这不是问题;该类包含由宏自动注册到外部库的信息。
【讨论】: