如何解决C ++中两个库之间的命名冲突?

时间:2010-01-30 00:36:31

标签: c++ namespaces

我正在使用两个大型库(GUI和网络),我很乐意做到

using namespace FirstLib;
using namespace SecondLib;

除了1个名为Foobar的单个类,其中名称发生冲突。

我是我的代码,我不使用FirstLib::Foobar。有没有办法说“在我的代码中,每当您看到Foobar时,请考虑SecondLib::Foobar

7 个答案:

答案 0 :(得分:6)

using namespaceevil!命名空间制作以防止出现此类问题!但是,说,试试:

using namespace FirstLib;
using namespace SecondLib;
using SecondLib::Foobar;

甚至(对于某些编译器):

using namespace FirstLib;
using namespace SecondLib;
typedef SecondLib::Foobar Foobar;

答案 1 :(得分:2)

奇怪的是,没有人建议用使用过的类名列表替换完整的名称空间使用。这个解决方案甚至在C++faq(我应该首先考虑的地方)。

如果我们不能说

  

包括所有FirstLib,但请删除SecondLib::Foobar

我们可以使用using-declarations我们需要的确切元素:

using FirstLib::Boids;
using FirstLib::Life;
// no using FirstLib::Foobar...

答案 2 :(得分:1)

你必须选择其中一个名称空间并删除'using',并显式调出所有类名。 C#解决了这个问题,但C ++并没有解决这个问题......

答案 3 :(得分:1)

你基本上回答了自己的问题。您必须明确说出要使用的课程,因此每当您使用该课程时都必须SecondLib::Foobar

答案 4 :(得分:1)

我认为没有办法排除名字。你可以带上整个地段,也可以单独带入。即使你引入了整个批次,你也可以通过完全限定它们来消除冲突名称的歧义。

但是,您可以使用typedef重命名违规类:

typedef Lib2::FooBar FooBaz;

我猜,在功能冲突的情况下,您可以使用函数指针“重命名”冲突的函数。


我想这是一种非解决方案。我可以理解使用声明的偶然动机 - 有时确实会有很多不同的名称,你会在整个地方使用它们 - 但如果只有一个是冲突的:明确的。无论如何,任何熟悉这些库的人都会感到困惑,因为两个名称空间都是导入的。

此外,使用声明遵循范围:您可以在一个函数中显示一个命名空间,而不是在另一个命名空间中显示 - 假设您甚至不在该函数中使用它。

答案 5 :(得分:0)

你试过了吗?

using SecondLib::Foobar;

答案 6 :(得分:0)

如果使用using namespace directove:

将所有元素从命名空间加载到当前范围
using namespace FirstLib;
using namespace SecondLib;

并且这些命名空间中的某些名称可能会发生冲突,那么您需要通过使用using声明明确告诉编译器您要在当前范围内使用哪个元素:

using SecondLib::Foobar;

正如C ++标准所说:

  

7.3.3使用声明

     

1使用声明引入了一个   命名到声明区域   其中出现使用声明。   该名称是名称的同义词   某个实体在别处宣布。

这一行要求编译器在SecondLib::Foobar看到使用using声明的当前作用域的其余部分时考虑Foobar

using指令和声明非常有用,但它们可能会导致您正在处理的问题。因此,将任何形式的using缩小到最小可能范围是一个好主意。您可以在其他命名空间

的范围内使用指令using namespace
namespace MyApp {
   using namespace ::SecondLib;
}

甚至是一个功能。这同样适用于using声明。因此,缩小其中任何一个的使用范围是个好主意:

void foo()
{
   ::SecondLib::Foobar fb;
}

这可能看起来很乏味,但只有当你打字时才会使用智能感知编辑器,因此成本非常小,但效益很大 - 没有混淆,可读的代码,没有编译问题。

在标题范围内不使用using namespace也是一个非常好的主意。见Header files usage - Best practices - C++

我自己的提示:当您需要使用任何这些类型时,请使用完全资格