C++中命名命名空间的最佳实践 // 当名称冲突时该怎么办?

3

好的,我知道我应该将我的代码嵌入命名空间中以处理名称冲突。

例如:

My-Header-Only-Library.hpp

    namespace AG {
    namespace My_Header_Only_Library {

    class Foo {
        ...
    };

    }
    }

所以我有一个AG::My_Header_Only_Library::Foo。

是的,我经常使用两个级别 - 第一个是AG、AFG、libAG等等 - 用于“我的”东西(例如我已经维护了一些库几十年,比如Valid<T>)。

我经常为各种模块创建子命名空间。

问题#1:命名空间名称有时会冲突。

是的:我发现所有命名空间名称AG、AFG、libAG都存在冲突。是的,我曾经遇到过与我相同缩写的公司。

(有一段时间我使用GLEW,认为这是一个非常独特的姓氏。那时候我是互联网上唯一一个叫Glew的人,并且是ARPAnet上仅有的第48个具有缩写AG的人。 (AG48)。但自那以后,OpenGL扩展Wrangler基本上将这一点从我身上夺走了。)

我想,“namespace AG_some_random_stuff_675567”不太可能发生冲突。人们这样做吗?使用一些较长的命名空间名称,然后再加上

using AG_lib = AG_some_random_stuff_675567

您是否曾尝试玩弄技巧,比如将命名空间的名称重新定义为其他内容。

例如:

#define AG something_more_unique

问题2:我有时会给、借或允许公司使用我的库。但我要求他们回馈修改,即不要分叉。
他们的编码约定可能不同。
我不希望他们更改命名空间名称,因为这会使合并他们的修改变得更困难。
问题:怎么办?让他们进行以下操作:
using Their_Name = AG_some_random_stuff_675567

下一步是什么?命名空间命名约定? - thang
3个回答

1

我通常从命名空间包含的内容、我的全名和创建日期开始——理论上这也不是100%免疫碰撞,但它非常接近1。如果你真的想要更接近免疫的东西,你可以生成一个GUID并使用它。

然后,当然,对于大多数正常使用,有一个更短的别名。不幸的是,你不能总是用别名代替完整的命名空间名称,但这就是生活。


对我来说,这很接近了——一个更常见的名字会提供更少的保护。

我将接受这个答案作为最佳答案,尽管我认为我的个人BKM将是这种方法和Java风格方法的混合。 - Krazy Glew

0

不要使用缩写,而是使用已分配的命名空间。例如,Java实践中反转您的完全限定域名非常有效。使用我的代码,我可以安全地使用

namespace com {
    namespace benvoigt {
    }
}

并且知道它不会与外部实体发生冲突,因为没有其他人能拥有 benvoigt.com 这个域名。


com 有什么作用?重名的名称是无用的。C++ 不是 Java。 - Potatoswatter
@BenVoigt Java规定命名空间对应于域名,而C++则没有。加拿大和计算机协会都非常大。com可以表示“common”或Microsoft Common Object Model。如果有人使用using namespace com;,因为那是他们放置自己的公共库的地方,那么你又回到了起点。 - Potatoswatter
1
@KrazyGlew 的意思是,使用 com_benvoigt 可以兼顾两者的优点。用作用域运算符替换下划线只会带来失败的结果。 - Potatoswatter
@Potatoswatter:我认为这是一个平均水平的改进,但是“_”在主机名中是合法的字母,所以它并不完全更好。 - Ben Voigt
@BenVoigt: 真糟糕,我的一个域名里有破折号,因此它不是合法的C/C++标识符。很快,将会有各种字符的主机名和域名存在,比如中文字符。 - Krazy Glew
显示剩余6条评论

0

你现在需要进行损害控制。收到你的库并与其内部名称冲突的公司将需要修改他们的客户端代码以消除冲突的库。

AG_some_random_stuff_675567 显然过于复杂,而 AG 显然(也许只是事后看来)太容易发生冲突了。选择一个相对独特的名称,这样未来的客户端就可以在不使用 using 别名的情况下使用它。例如 all_good。(虽然,如果要求客户端添加自己的 using 别名不会引起营销或支持问题,那么一个带有 random_stuff 的命名空间将是完全安全的。)

然后,在你自己的代码中添加 using namespace AG = all_good;,并指导旧客户端执行相同的操作以实现向后兼容性。

也许可以使用预处理器标志来帮助迁移客户端,通过选择谁在全局命名空间中获得 using 指令,但绝不能使用预处理器宏来重命名命名空间!尤其是像 AG 这样已经被证明会发生冲突的名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接