[英]Why is the ADL not working when `using directive` is used?
这是一个类似的问题 ,但是在这个问题中它有效,但是,它在以下情况下失败,为什么?
namespace A
{
int k;
}
namespace B
{
class test{};
void k(const test&){/*do something*/}
}
int main()
{
using namespace A;
k(B::test());//compile error
}
错误信息是: “'A :: k'不能用作函数”(gcc 6.3.0)
也就是说,编译器不会尝试执行ADL ,也不会在namespace B
找到void k(const test&)
但是,我认为ADL应该在这种情况下工作,因为上面的代码不属于以下情况:
引自cppref
首先,如果通常的非限定查找生成的查找集包含以下任何内容,则不考虑依赖于参数的查找:
1)集体成员的声明
2)块范围内的函数声明 (不是使用声明)
3)任何声明这不是一个函数或函数模板(例如,功能对象或其他变量,其名称冲突与同时被查找的功能名称)
更确切地说,这里using namespace A
不会引入任何声明:
引自cppref
using-directive不会向它出现的声明区域添加任何名称(与using-declaration不同),因此不会阻止声明相同的名称。
函数调用的名称查找包含两部分:
根据N4659 [basic.lookup.argdep] / 3,正常的非限定查找首先发生; 如果找到正常的非限定查找,则ADL阶段不会继续:
- 集体成员的声明,或
- 块范围函数声明,它不是using声明,或
- 既不是函数也不是函数模板的声明。
在您的代码中,正常的非限定查找确实找到了A::k
如前一个问题中所述 。 因此,此代码不会发生ADL。
using-directive指定指定命名空间中的名称可以在using-directive出现在using-directive之后的范围内使用。 在非限定名称查找(6.4.1)期间,名称看起来好像是在最近的封闭命名空间中声明的,其中包含using-directive和指定的命名空间。
因此,非限定名称查找将找到A :: k,这就是错误的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.