我在我的代码中使用JUCE库和许多Boost标头。 Juce将“T”定义为宏(呻吟),Boost经常在其模板定义中使用“T”。结果是,如果你以某种方式在Boost头之前包含JUCE头,那么预处理器会在Boost代码中扩展JUCE宏,然后编译器就会无可救药地丢失。
在大多数情况下保持我的包含顺序并不难,但是如果你有一个包含其他类的JUCE类,并且某个链上的某个文件包含Boost,并且如果有的话,它会变得棘手需要JUCE之前的文件包括你遇到麻烦。
我最初的希望是解决这个问题
#undef T
在任何包含Boost之前。但问题是,如果我不重新定义它,那么其他代码会混淆“T”未被声明。
然后我想也许我可以像这样做一些循环的#define技巧:
// some includes up here
#define ___T___ T
#undef T
// include boost headers here
#define T ___T___
#undef ___T___
丑陋,但我认为它可能会奏效。
可悲的是没有。我在使用“T”作为宏
的地方出错'___T___' was not declared in this scope.
有没有办法让这两个库可靠地一起工作?
答案 0 :(得分:61)
正如greyfade指出的那样,你的___T___
技巧不起作用,因为预处理器是一个非常简单的生物。另一种方法是使用pragma指令:
// juice includes here
#pragma push_macro("T")
#undef T
// include boost headers here
#pragma pop_macro("T")
这应该适用于MSVC ++,GCC已添加对pop_macro
和push_macro
的支持,以便与之兼容。从技术上讲,它依赖于实现,但我认为没有一种标准的方法可以暂时抑制定义。
答案 1 :(得分:11)
你可以将违规库包装在另一个包含中并将#define T陷入其中吗?
例如:
JUICE_wrapper.h:
#include "juice.h"
#undef T
main.cpp:
#include "JUICE_wrapper.h"
#include "boost.h"
rest of code....
答案 2 :(得分:4)
然后我想也许我可以像这样做一些循环的#define技巧:
C预处理器不能以这种方式工作。预处理器符号的定义与给定符号的意义不同,意味着在例如时定义一个函数。
将预处理器视为文本替换引擎可能会有所帮助。定义符号时,它将被视为直接文本替换,直到文件结尾或未定义。它的值不会存储在任何地方,因此无法复制。因此,在您T
之后恢复#undef
定义的唯一方法是在代码中的新#define
中完全重现其值。
您可以做的最好的事情就是不要使用Boost或请求JUCE的开发人员不要将T
用作宏。 (或者,最糟糕的情况是,通过更改宏的名称来自行修复。)