名字查找是当程序中出现一个名字时,将其与引入它的声明联系起来的过程。
#include<iostream>
int main(){
std::cout << "test\n" << std::endl;
return 0;
}
在了解以下步骤之前要学习几个术语:
-
无限定名字(Unqualified name):即并非出现在作用域解析运算符 :: 右边的名字
-
有限定名字(qualified name):是出现在作用域解析操作符 :: 右边的名字
-
实参依赖查找(argument-dependent lookup):一组对无限定名查找的规则,在通常无限定名字查找所考虑的作用域和命名空间之外,还在其各个实参的命名空间中查找这些函数。
-
模板实参推导 :为实例化一个函数模板,每个模板实参都必为已知的,但并非必须指定每个模板实参。只要可能,编译器都会从函数实参推导缺失的模板实参。
为了编译std::cout << "test\n" << std::endl;编译器进行了以下这些工作
-
名字std进行无限定名字查找,在头文件<iostream>中找到命名空间std的声明;
-
名字cout进行有限定名字查找,在命名空间std中找到一个变量的声明;
-
对第一个operator<<名字进行实参依赖查找(ADL),ADL在左实参数cout的命名空间std中找到多个std::ostream::operator<<重载函数模板的声明;
-
编译器进行模板实参推导,推导出std::ostream& std::operator<< <std::char_traits<char>>(std::ostream&,const char*);
-
名字endl进行有限定名字查找,在命名空间std中找到一个函数模板声明
-
对std::endl进行模板实参推导,推导出 std::ostream& std::endl<char, std::char_traits<char>>(std::ostream&);
-
第二个operator<<进行实参依赖查找,和模板实参推导,得到std::ostream& std::operator<< (std::ostream&);
网友评论