即使在使用名称空间之后,如果名称冲突,该怎么办

What if there is a name clash even after using namespace?

本文关键字:如果 冲突 怎么办 空间 之后      更新时间:2023-10-16

我们通常使用名称空间来避免C++中的名称冲突。但是,如果有两个不同的库有一个类,具有相同的命名空间名称和类名,该怎么办?附近有工作吗?

(附言:我很确定,这是一种罕见的情况,我从未面对过,只是碰巧想到了)

这个想法是使用与公司/集团本身相关的东西
这样就避免了碰撞
专业图书馆不太可能选择像MyNamespace这样琐碎的东西。

就像Company::Project::Module

这在java中更为清楚,因为您有org.apache etc

这可能会发生,但不太可能对你造成太大伤害。不仅名称空间名称必须完全相同,而且还必须实际使用这两个库。很可能,如果它们以某种合理的方式命名了名称空间,它们的名称将表明它们的用途——即使有两个库使用GenericXMLParser作为名称空间,并且可能有一些共同的类名,你真的希望在一个项目中同时使用它们吗?

这确实会使某些命名空间名称成为一个坏主意,例如boostOgre。任何使用这些库的人(除了原始用户)都应该预料到他们的库在许多情况下是不可用的。一个不太常见的名字,比如Pie,可能在大多数情况下对大多数人来说都很好。如果使用Pie的两个库都得到广泛使用,其中一个可能不得不更改;在这种情况下,可以使用名称空间重命名技巧来保持与旧代码的向后兼容性。

您可以使用重命名其中一个命名空间

namespace <new> = <old>;

但这只会让你走到这一步。这里有一个例子:

namespace aaa {
   int foo() { return 42; }
}
namespace zzz {
   int foo() { return -42; }
}
namespace bbb = aaa;
int main() {
    aaa::foo();         //Original namespace is still there
    bbb::foo();  //but it is also available with a new name
    zzz::foo();  //No clash, that's what namespaces are for
    return 0;
}

但是,由于重命名实际上只是一个别名,所以aaa命名空间会保留下来。这段代码会给你一个重复的符号错误(无论它在.h文件中埋得有多深):

namespace aaa {
   int foo() { return 42; }
}
namespace aaa {
   int foo() { return -42; }
}

您可以通过在自己的名称空间声明中封装冲突的名称空间来绕过它,如下所示:

#include <stdio.h>
namespace aaa {
   int foo() { return 42; }
}
namespace zzz {
#include "clash.h"
}
namespace aaa2 = zzz::aaa;
int main() {
    printf("%dn", aaa::foo());   //Original works
    printf("%dn", aaa2::foo());  //Non-clashing through alias
    printf("%dn", zzz::aaa::foo());  //Non-clashing real name
    return 0;
}

但该解决方案也只能在琐碎的代码中工作,因为clash.h中包含的所有文件最终都将位于zzz命名空间中。

+不过,我认为重命名std是被禁止的,哪怕只是出于常识。

相关文章: