我可以重新定义一个C ++macros,然后定义它?

我在我的代码中同时使用了JUCE库和一些Boost头文件。 Juce将“T”定义为一个macros(呻吟),Boost经常在其模板定义中使用“T”。 结果是,如果你在Boost头文件之前包含了JUCE头文件,预处理程序就会在Boost代码中扩展JUCEmacros,然后编译器就会失去希望。

在大多数情况下保持我的包含顺序并不困难,但是当你有一个JUCE类包含一些其他的类,并且链上的某个文件包含了Boost,并且它之前的任何文件需要一个JUCE包括你有麻烦。

我最初的希望在于解决这个问题

#undef T 

之前任何包括提升。 但问题是,如果我不重新定义它,那么其他代码会感到困惑,“T”没有被声明。

然后我想,也许我可以这样做一些循环的#define技巧:

 // some includes up here #define ___T___ T #undef T // include boost headers here #define T ___T___ #undef ___T___ 

丑,但我认为它可能工作。

可悲的是。 我在使用“T”作为macros的地方出现错误

 '___T___' was not declared in this scope. 

有没有办法使这两个库可靠地一起工作?

正如greyfade指出的那样,你的___T___技巧是行不通的,因为预处理器是一个非常简单的生物。 另一种方法是使用编译指示:

  // juice includes here #pragma push_macro("T") #undef T // include boost headers here #pragma pop_macro("T") 

这应该在MSVC ++中工作,GCC已经添加了对pop_macropush_macro的兼容性支持。 从技术上来说,这是依赖于实现的,但是我不认为有一种暂时压制定义的标准方法。

你可以包装在另一个包括犯罪图书馆和陷阱的#define T里面?

例如:

 JUICE_wrapper.h: #include "juice.h" #undef T main.cpp: #include "JUICE_wrapper.h" #include "boost.h" rest of code.... 

然后我想,也许我可以这样做一些循环的#define技巧:

C预处理器不能以这种方式工作。 预处理器符号的定义并不像在定义函数时给定符号那样。

将预处理器视为文本replace引擎可能会有帮助。 当一个符号被定义时,它被视为一个直接的文本replace,直到文件结尾或者直到它被定义为止。 它的值不存储在任何地方,所以不能被复制。 因此,在#undef之后,恢复T的定义的唯一方法就是在代码的后面在#define完全重现它的值。

你可以做的最好的就是不要使用Boost或者请求JUCE的开发者不要使用T作为macros。 (或者,最坏的情况下,通过更改macros名称来修复它。)