2012-02-02 68 views
2

我们通常使用名称空间来避免C++中的名称冲突。但是如果有两个不同的库有一个类,它具有相同的名称空间名称和类名?有没有解决办法?即使在使用命名空间之后还有名称冲突怎么办?

(PS:我敢肯定,它的一个罕见的情况下,我从来没有遇到它,刚好过我的脑海)

+0

0_o,起诉这两个图书馆的创造者? xD – 2012-02-02 15:59:36

回答

0

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

这确实使某些命名空间名称是一个糟糕的主意,例如boostOgre。任何人使用这些(除原来的用户)应该期望他们的库在许多情况下不可用。一个不太常见的名字,如Pie,在绝大多数情况下,对于绝大多数人来说可能会很好。如果两个使用Pie的库被广泛使用,则可能需要更改;在这种情况下,可以使用名称空间重命名技巧来保持与旧代码的向后兼容性。

1

的想法是使用相关的公司/集团本身的东西。
这样避免了碰撞。
专业图书馆很难选择像MyNamespace这样微不足道的东西。

它会像Company::Project::Module

,你必须org.apache etc

+0

Java方案的优点是存在名称所有权的中央注册表。即使每个人都是专业人士,如果在不同国家/地区有两个或多或少同名的组织,C++问题也会出现。在Java中,它们是'com.apple'和'uk.co.苹果“,但在C++中,你最好只希望他们在开始发布使用命名空间”apple“的C++库之前就知道这个问题。 – 2012-02-02 16:08:16

+0

就我个人而言,我不会订阅使用已久的公司名称作为命名空间名称:公司消失的机会比其代码更好:它们经常消失,因为它们被另一家公司掌握代码。辩护?有创意,不要打电话 – 2012-02-02 17:31:46

+0

@DietmarKuhl:你有一点,但是当你为一家公司编写代码时,它是公司的专利。所以你不能随意使用惯例。同一产品线应该有一致性。 – Cratylus 2012-02-02 17:46:40

0

可以重命名的命名空间中的一个与

namespace <new> = <old>; 

但只会让你至今这甚至在Java清晰。这里有一个例子:

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("%d\n", aaa::foo()); //Original works 
    printf("%d\n", aaa2::foo()); //Non-clashing through alias 
    printf("%d\n", zzz::aaa::foo()); //Non-clashing real name 
    return 0; 
} 

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

+我认为重命名std虽然只是通过常识是被禁止的。

+0

这没有帮助,您仍然无法在同一个可执行文件中链接这两个类。 – 2012-02-02 16:05:52

+0

我不知道这意味着什么 – 2012-02-02 19:17:19

+0

@SteveJessop是对的。只要你不需要链接,这个技巧就可以工作;)我编辑了我的答案。 – ixe013 2012-02-03 16:02:22