ADL,参数相关查找,也称作为Koenig查找(以Andrew Koenig的名字命名,有兴趣可以看Scott Meyer的文章The Most Important C++ People...Ever),是指在编译器对无限定域的函数调用进行名字查找时,所应用的一种查找规则。
f(x, y, z);
//
unqualified
N::f(x, y, z);
//
qualified
Koenig Lookup(simplified): If you supply a function argument of class type (here x, of type A::X), then to look up the correct function name the compiler considers matching names in the namespace (here A) containing the argument's type.
#include <iostream>
using
namespace std;
namespace Koenig
{
class KoenigArg
{
public:
ostream& print(ostream& out) const
{
out<<member_<<endl;
}
KoenigArg(int member = 5) : member_(member){}
private:
int member_;
};

inline ostream& operator<<(ostream& out, const KoenigArg& kArg)
{
return kArg.print(out);
}
}
int main()
{
Koenig::KoenigArg karg(10);
cout<<karg;
char c;cin>>c;
return 0;
}
我们通常都会写如上的代码,使用operator<<打印对象的状态,但是ostream& operator<<(ostream& out, const KoenigArg& kArg) 的定义是处于名字空间Koenig,为什么编译器在解析main函数(全局域)里面的operator<<调用时,它能够正确定位到Koenig名字空间里面的operator<<?这是因为根据Koenig查找规则,编译器需要把参数类型KoenigArg所在的名字空间Koenig也加入对operator<<调用的名字查找范围中。
如果没有Koenig查找规则,我们就无法直接写cout<<karg;,而是需要写类似Koenig::operator<<(std::cout, karg); 这样的代码(使用完全限定名)。嗯,即不直观也不方便是吗?更重要的是如果我们写的是模版代码,在模版参数还没有实例化之前,我们根本就不知道参数所处的名字空间,比如:
template<typename T>
void print(
const T& value)
{
std::cout<<value;
}
print(karg);
A class describes a set of data, along with the functions that operate on that data.
are logically part of X, because they form part of the interface of X.
本文详细介绍了ADL(关联声明查找),又称Koenig查找,在C++编译过程中的作用及其工作原理。通过具体代码示例展示了如何利用Koenig查找规则实现跨名字空间的函数调用,并探讨了其带来的便利性和争议。
946

被折叠的 条评论
为什么被折叠?



