如何解决两个不使用命名空间的第三方库之间的类名冲突?

Posted

技术标签:

【中文标题】如何解决两个不使用命名空间的第三方库之间的类名冲突?【英文标题】:How to resolve class-name conflicts between two third-party libraries that do not use namespaces? 【发布时间】:2018-05-18 10:36:58 【问题描述】:

我的项目使用了两个第三方开源库,两个库都定义了BDD类型,并且都不使用命名空间。

有没有办法解决名称冲突?也许强制一个库进入自定义命名空间?

附加信息: 第一个库仅使用BDD 作为类型别名(typedef int BDD),因此它不会调用BDD 上的任何方法。

【问题讨论】:

您可能需要为其中一个创建一些包装器,而不是#include 包装器组件标题中的冲突标题。也许是某种pimpl?这有一些混乱的开销,因为您几乎需要复制类的接口(成员和非成员函数),并将定义转发到这些函数的库版本。 它们是开源库吗? 你的意思是两个 BDD 都是#define 另外,他们有编译过的组件吗? 但是,在您的特定场景中使用我的答案要简单得多,因此我将取消它并对其进行编辑以包含新信息。 【参考方案1】:

由于您的一个库仅使用BDD 作为int 的别名(我假设此库称为lib1,另一个称为lib2),您只需更改此别名的名称通过告诉预处理器在包含库之前重命名它,如下所示:

#define BDD BDD_lib1
#include <lib1>
#undef BDD

#include <lib2>

如果您需要在代码中使用 lib1 中的名称 BDD,则可以使用 BDD_lib1 引用它(或者如果您不担心其类型会更改,则只需使用 int lib1 的未来版本。


但是,我认为这种方法只是一种解决方法,而不是真正的解决方案,因此您可能需要考虑按照@YSC 在他的回答中建议的那样做,并提供一个补丁,这样其他尝试使用这些库的人就不会遇到同样的问题。


这是否适用于更一般的场景?

如果BDD 不仅仅是一个简单的类型别名,而是一个单独的类,那么由于 C++ 的名称修改可能会遇到麻烦,所以这种方法只有在名称 BDD 在任何情况下都不重要的情况下才有效会出现名称修改。这或多或少地施加了以下限制:

BDD 不能有任何非内联方法 依赖于BDD 的任何类型(例如,类模板template &lt;typename&gt; class A; 的特化A&lt;BDD&gt; 是依赖于`BDD 的类型)不得有任何非内联方法 其参数列表包含取决于 BDD 的类型的所有函数/方法必须是内联的,或者具有 C 链接

【讨论】:

我认为您的编辑是您回答的真正附加值。 +1 谢谢,这就是我添加它的原因 - 搜索此内容的其他人不太可能遇到与 OP 完全相同的情况,因此我认为解释何时以及何时可以这样做是个好主意它无法工作。【参考方案2】:

由于这些库是开源的,您可以为其中至少一个添加命名空间,并将您的补丁提供给库维护者。

您将实现两件事:

    修复您的特定命名冲突,并且 让世界变得更美好。

【讨论】:

你可以,我的意思是你应该

以上是关于如何解决两个不使用命名空间的第三方库之间的类名冲突?的主要内容,如果未能解决你的问题,请参考以下文章

thinkphp 5.0 命名空间

使用jquery时$符号冲突问题解决方案

thinkphp5.0命名空间

如何使用标准库包名称解决 Python 包中的命名空间冲突?

Android开发——如何解决三方库中的类名冲突问题

Android开发——如何解决三方库中的类名冲突问题