![](/img/trans.png)
[英]How to resolve a name collision between a C++ namespace and a global function?
[英]Name collision between c++ library namespace and C linux function
Linux <ncurses.h>
头定义了函数meta
,C ++元编程库meta
将其所有代码放在全局命名空间meta
。
我怎样才能在同一个C ++程序中使用它们(不一定是相同的TU,但那会很好)? 有没有办法解决名称冲突?
我可以想到两个脆弱的解决方法,但它们很容易破解:
解决方法A:
namespace linux { #include <ncurses.h> } // namespace linux using linux::max_align_t; // ncurses assumes it is in the global namespace #include <meta/meta.hpp>
编译但可能无法链接,因为在全局命名空间中需要ncurses
符号。
解决方法B:
#include <ncurses.h> namespace cpp { #include <meta/meta.hpp> } // namespace cpp
非常脆弱,因为它只有在meta
库不假设它的任何符号都在全局命名空间中时才会起作用。 也就是说,如果库需要在内部消除符号歧义并使用::meta::symbol_name
,那么这种方法就会破坏。
我建议解决方法C:隔离您的代码,以便meta
库使用和ncurses
使用在项目中的单独翻译单元中。 这种方式在任何特定的翻译单元中,没有一个符号被用作命名空间和全局函数。
我有理由相信A和B都不会真正起作用,至少是给定的。 你已经指出了其中一个,但我认为这两个中的可能性较小。 有两个问题基本上是彼此的镜像。
如果ncurses
的代码被声明为extern "C"
(对于许多使用C ++的C库来说是典型的),用命名空间包围它们实际上不会起作用 - extern "C"
声明基本上忽略了名称空间和在全局命名空间中声明一个函数。 命名空间不会改变任何东西,你仍然会发生碰撞。
如果<ncurses.h>
的内容未声明为extern "C"
,那么您将遇到引用的问题:库是使用全局命名空间中的函数构建的,但是客户端代码看到了代码的定义。 linux
命名空间。 由于命名空间会影响受损的名称(这就是它如何防止冲突),因此您的代码将无法链接。 所有linux::*
函数都将显示为未解析的外部。
为了使这项工作,你需要确保没有任何库代码的声明extern "C"
,并指定报头内的命名空间(和库源文件),并重新编译这些声明的库,所以库并且其客户端代码同意该代码所在的命名空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.