我正在使用两个大型库(GUI和网络),我很乐意做到
using namespace FirstLib;
using namespace SecondLib;
除了1个名为Foobar
的单个类,其中名称发生冲突。
我是我的代码,我不使用FirstLib::Foobar
。有没有办法说“在我的代码中,每当您看到Foobar
时,请考虑SecondLib::Foobar
?
答案 0 :(得分:6)
using namespace
是evil!命名空间制作以防止出现此类问题!但是,说,试试:
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++
我自己的提示:当您需要使用任何这些类型时,请使用完全资格