这里有一个简化的例子。假设我正在使用库B和C编写程序A。Niether库的源代码可以更改,并且它们是唯一可用的库。库B有一个合理的#define
,而库C有一个别名为愚蠢的#define
//library_b_header.hpp
#pragma once
#define uint16 unsigned short
//...
//library_c_header.hpp
#pragma once
#define uint16 unsigned char
我的大多数先例都是这样的问题。有一个答案很有帮助,涵盖了我看到的一系列建议(转述):
- 在您自己的代码中添加
#undef
- 不要直接包含
library_c_header.hpp
。如果其他库为您包含它,请不要直接包含。相反,将其包含在一个单独的.cpp
文件中,然后可以在其标头中公开包装器函数 - 重命名您自己的符号
第二个选项接近我的正常解决方案,但库C很大;我不可能包装所有的功能。即使我可以,也很有可能会出错,而且它肯定不能移植到C库的新版本(这也是经常发生的)。
第三个选项不起作用,因为它在任何地方都使用。与之冲突的不仅仅是我;它与相冲突,实际上所有其他。我想这可以完成。这只是一个错误的#define
,它应该死
这里的第一个选项最接近我正在尝试的。第二个问题是#include
ing库C依赖于库B中定义的令牌。
我得到的最远的是:
#include <library_b/library_b_header.hpp>
#define library_b_uint16 uint16
#undef uint16
#ifdef LIBRARY_B_SYMBOL
#include <library_c/library_c_header.hpp>
#undef uint16
#define uint16 library_b_uint16
#endif
这显然不起作用,但也许它表达了我的意图。还有什么我可以试试的吗?
如果您的编译器支持push_macro
和pop_macro
杂注,您可能可以这样使用它们:
#include <library_b/library_b_header.hpp>
#pragma push_macro("uint16")
#undef uint16
#include <library_c/library_c_header.hpp>
#pragma pop_macro("uint16")
(这些杂注是非标准的,但它们受到广泛支持。Visual C++、gcc、clang和"英特尔C++编译器"都支持它们。)
是的,您需要在包含库C中定义此宏的标头的任何位置执行此操作,但这通常可以通过编写自己的标头来简化,该标头封装库C标头的包含,然后在项目中需要库C的任何位置包含该标头。