Fla*_*een 3 c++ name-lookup argument-dependent-lookup
考虑http://en.cppreference.com/w/cpp/language/adl中描述的此示例:
namespace A {
struct X;
struct Y;
void f(int);
void g(X);
}
namespace B {
void f(int i) {
f(i); // calls B::f (endless recursion)
}
void g(A::X x) {
g(x); // Error: ambiguous between B::g (ordinary lookup)
// and A::g (argument-dependent lookup)
}
void h(A::Y y) {
h(y); // calls B::h (endless recursion): ADL examines the A namespace
// but finds no A::h, so only B::h from ordinary lookup is used
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道为什么出现歧义,因为如果不考虑ADL规则
"由通常的非限定查找生成的查找集包含以下任何内容".
这里B :: g可以通过非限定查找找到,如http://en.cppreference.com/w/cpp/language/unqualified_lookup中所述,这要归功于规则
用于在函数的定义中使用,无论是在其主体或作为默认参数,其中函数是用户声明的或全局命名空间,该块的构件,其中所使用的名称的使用之前被搜索的一部分的名称名称,然后在该块的开始之前搜索封闭块等,直到到达作为功能体的块.然后搜索声明函数的名称空间,直到使用该名称的函数的定义(不一定是声明),然后是封闭的名称空间等.
那么我的问题是为什么在这种情况下考虑ADL规则?
完整的报价是
首先,如果通常的非限定查找生成的查找集包含以下任何内容,则不考虑依赖于参数的查找:
- 集体成员的声明
- 块范围内的函数声明(不是使用声明)
- 任何不是函数或函数模板的声明(例如,函数对象或其名称与正在查找的函数名称冲突的其他变量)
这意味着只有当非限定查找产生上述三个结果之一时,才会忽略ADL.由于我们没有处理类成员,因此该函数在命名空间范围内声明,而不是块作用域,我们只查找继续使用的函数并使用ADL.