问题描述
我正在学习使用指令,并试图了解使用指令的名称查找规则,但是我遇到了这个问题,找不到任何解释。
问题看起来像这样:
prog1 :名称空间C
在名称空间A
之外:
#include <iostream>
namespace C
{
namespace Detail
{
void func()
{
std::cout << "C::Detail::func " << "\n";
}
}
}
namespace A
{
namespace Detail
{
void func()
{
std::cout << "A::Detail::func " << "\n";
}
}
using namespace C;
void func2()
{
Detail::func(); // no conflict,select A::Detail::func
}
}
int main()
{
A::func2();
return 0;
}
程序成功执行并输出A::Detail::func
。
当我将namespace C
移到namespace A
内时,出现编译器错误:
prog2 :名称空间C
在名称空间A
内:
namespace A
{
namespace C
{
namespace Detail
{
void func()
{
std::cout << "C::Detail::func " << "\n";
}
}
}
namespace Detail
{
void func()
{
std::cout << "A::Detail::func " << "\n";
}
}
using namespace C;
void func2()
{
Detail::func(); // conflict for A::Detail::func and A::C::Detail::func
}
}
int main()
{
A::func2();
return 0;
}
程序出现以下编译器错误:
prog.cc:27:9: error: reference to 'Detail' is ambiguous
Detail::func();
^
prog.cc:15:15: note: candidate found by name lookup is 'A::Detail'
namespace Detail
^
prog.cc:6:19: note: candidate found by name lookup is 'A::C::Detail'
namespace Detail
^
1 error generated.
编译器:GCC 9.3.0和CLANG 9.0.0的结果相同。
我的问题:
为什么结果不同,在这种情况下,限定名称查找的具体规则是什么?
解决方法
[namespace.udir] / 2 using-directive (指定使用命名空间中的名称)可以在 using-使用范围内使用指令出现在 using-directive 之后。在非限定名称查找(6.4.1)期间,名称显示为,就像在最近的封闭名称空间中声明的名称一样,该名称空间同时包含 using-directive 和指定的名称空间。 [注意:在本文中,“包含”是指“直接或间接包含”。 -尾注]
强调我的。在 prog1 中,最接近的名称空间是全局名称空间,并且A::Detail
位于::Detail
之前。在 prog2 中,最接近的命名空间是A
,因此名称查找会找到两个不同的命名空间,都命名为A::Detail
。