13

是否可以有 2 个同名但参数不同的宏?像这样的东西:

#define FI(value) do {l<<value;  Doit(l); } while(0)
#define FI(value, level) do {l<<value ; Doit(l,level); } while(0)
4

4 回答 4

12

这不可能。
不能重新定义符号名称。与函数不同,宏不能重载。逻辑上认为宏是用于纯文本替换的,那么如何为同一个实体替换两个不同的东西呢?

另一种更好的解决方案:
您可以编写一个内联函数来实现相同的结果。它为您提供了类型检查的额外优势,并使您免于宏的模糊副作用。

于 2013-01-02T14:42:08.030 回答
2

这会奏效。

#define FI(value, ...) FI_(value, ##__VA_ARGS__, 2, 1)
#define FI_(value, level, n, ...) FI##n(value, level)
#define FI1(value, ...) do {l << value; Doit(l);} while (0)
#define FI2(value, level) do {l << value; Doit(l, level);} while (0)
于 2016-04-16T20:37:27.970 回答
1

实际上这是可能的。但是,它会导致编译器关于重新定义的警告。

有关更多详细信息,请参见:http: //efesx.com/2010/08/31/overloading-macros/

于 2013-01-02T14:47:42.397 回答
1

在这种情况下,您确实应该使用内联函数。对您正在使用的类型一无所知,可能的实现可能如下所示:

template<typename T>
inline void fi(T & l, const T & value) {
   l << value;
   Doit(l);
}

template<typename T>
inline void fi(T & l, const T & value, const T & level) {
   l << value;
   Doit(l, level);
}

如果您遇到必须坚持使用宏的情况,您将不得不解决这个限制,即它们不能被重载,至少不是按照标准。为了“重载”它们,我们只需在宏名称上写上参数的数量,这是一种常见的做法(事实上,即使是 OpenGL 库也使用这种方法来“重载”C 函数)。

#define FI1(value) do {l<<value;  Doit(l); } while(0)
#define FI2(value, level) do {l<<value ; Doit(l,level); } while(0)
于 2013-01-02T14:59:29.553 回答