根据unqualified lookup in cppreference.com:
对于函数定义中使用的名称,无论是在其主体中还是作为default参数的一部分,其中函数是用户声明的或全局命名空间的成员,之前搜索使用该名称的块使用该名称,然后在该块的开始之前搜索封闭块等,直到到达作为函数体的块。 然后搜索声明函数的名称空间,直到使用该名称的函数的定义(不一定是声明),然后是封闭的名称空间等。
所以我认为在全局命名空间范围内定义的函数名称只能通过不定型查找找到。但是,以下代码无法编译:
#include <iterator>
#include <iostream>
namespace AA{
class AAA{};
};
using namespace AA;
int begin(AAA ){
return 3;
}
int main(){
using std::begin; // to add std::begin in the name candidate set
auto x = AAA();
return begin(x); // compile error, ::begin cannot be found
}
GCC(6.1.1)和Clang(3.8.0)都报告相同的error。
而且,我删除using std::begin
语句或将class AAA
移至namespace AA
,上述程序成功编译。所以我认为一旦通过名称查找找到begin
,就会通过重载决策来选择它。因此问题是:为什么我在上面的代码案例中找不到在全局范围内声明和定义的begin
函数?
答案 0 :(得分:1)
请注意,unqualified name lookup将在找到名称时停止(在某个范围内),然后搜索其他范围。对于示例代码,名称begin
将在main()
的函数范围内找到(引用std::begin
),然后名称查找停止,因此全局范围内的名称赢了&# 39;检查。
...,名称查找检查范围如下所述,直到它找到至少一个任何类型的声明,此时查找停止,不再检查其他范围。
从你发布的引文(我强调添加):
等,直到到达功能体的块。 (名称查找将在此处停止,即在main()函数体的块中)
然后命名空间...... (无法搜索更多命名空间。)