我可以重新定义 C++ 吗?宏然后定义回来?

发布于 2024-08-12 18:20:23 字数 710 浏览 3 评论 0原文

我在代码中使用了 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.

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

I am using both the JUCE Library and a number of Boost headers in my code. Juce defines "T" as a macro (groan), and Boost often uses "T" in it's template definitions. The result is that if you somehow include the JUCE headers before the Boost headers the preprocessor expands the JUCE macro in the Boost code, and then the compiler gets hopelessly lost.

Keeping my includes in the right order isn't hard most of the time, but it can get tricky when you have a JUCE class that includes some other classes and somewhere up the chain one file includes Boost, and if any of the files before it needed a JUCE include you're in trouble.

My initial hope at fixing this was to

#undef T

before any includes for Boost. But the problem is, if I don't re-define it, then other code gets confused that "T" is not declared.

I then thought that maybe I could do some circular #define trickery like so:

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

Ugly, but I thought it may work.

Sadly no. I get errors in places using "T" as a macro that

'___T___' was not declared in this scope.

Is there a way to make these two libraries work reliably together?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

农村范ル 2024-08-19 18:20:23

正如 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 的支持以与其兼容。从技术上讲,它虽然依赖于实现,但我认为没有一种标准方法可以暂时抑制该定义。

As greyfade pointed out, your ___T___ trick doesn't work because the preprocessor is a pretty simple creature. An alternative approach is to use pragma directives:

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

That should work in MSVC++ and GCC has added support for pop_macro and push_macro for compatibility with it. Technically it is implementation-dependent though, but I don't think there's a standard way of temporarily suppressing the definition.

习ぎ惯性依靠 2024-08-19 18:20:23

您可以将有问题的库包装在另一个包含中并将 #define T 捕获在其中吗?

例如:

JUICE_wrapper.h:     
#include "juice.h"
#undef T

main.cpp:    
#include "JUICE_wrapper.h"    
#include "boost.h"

 rest of code....

Can you wrap the offending library in another include and trap the #define T inside?

eg:

JUICE_wrapper.h:     
#include "juice.h"
#undef T

main.cpp:    
#include "JUICE_wrapper.h"    
#include "boost.h"

 rest of code....
战皆罪 2024-08-19 18:20:23

然后我想也许我可以做一些循环#define 欺骗,如下所示:

C 预处理器不是这样工作的。预处理器符号的定义方式与在定义函数时赋予符号含义不同。例如

将预处理器视为文本替换引擎可能会有所帮助。定义符号后,它将被视为直接文本替换,直到文件末尾或直到未定义为止。它的值不存储在任何地方,因此无法复制。因此,在 #undef 编辑后恢复 T 定义的唯一方法是在新的 #define 中完全重现其值> 稍后在您的代码中。

您能做的最好的事情就是不使用 Boost 或请求 JUCE 的开发人员不要使用 T 作为宏。 (或者,最坏的情况是,通过更改宏的名称自行修复。)

I then thought that maybe I could do some circular #define trickery like so:

The C Preprocessor doesn't work this way. Preprocessor symbols aren't defined in the same sense that a symbol is given meaning when, e.g., you define a function.

It might help to think of the preprocessor as a text-replace engine. When a symbol is defined, it's treated as a straight-up text-replace until the end of the file or until it's undefined. Its value is not stored anywhere, and so, can't be copied. Therefore, the only way to restore the definition of T after you've #undefed it is to completely reproduce its value in a new #define later in your code.

The best you can do is to simply not use Boost or petition the developers of JUCE to not use T as a macro. (Or, worst case, fix it yourself by changing the name of the macro.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文