关于ADL的查找顺序

argument-dependent lookup或Koening lookup法则

当我们给函数传递一个类类型的对象时,首先会在常规的作用域查找,其次在实参类所属的命名空间查找。
查找顺序如下:
1. 先在本作用域内查找;
2. 在实参的命名空间 和 全局作用域中 同时查找;

这一规则也叫做argument-dependent lookup或Koening lookup法则。这一规则对传递类的引用或指针的调用同样有效。如果名称后面的括号里面有一个或多个实参表达式,那么ADL将会查找这些实参直接相关的所有namespace和class。其中,类包括直接基类和间接基类。Andrew Koenig首次提出了ADL,这也是为什么ADL有时也称为koenig查找的原因。最初ADL引入的动机只是为了方便编写a+b,其中a和b至少有一个是用户自定义类型。如果没有ADL,则就要写为N::operator+(a,b)。


下面我们用程序来验证一下:

#include <iostream>
using std::cout;
using std::endl;

namespace X {
	void f(int) {
		cout << "namespace X void f(int)" << endl;
	}
}

namespace N {
	using namespace X;
	enum E{ e1 };
	void f(E) {				
		cout << "N::f(N::E) is called!!!" << endl;
	}
}

void f(N::E) {				
	cout << "::f(N::E) is called!!!" << endl;
}

int main() {
	::f(N::e1);
	f(N::e1);    //error: call of overloaded 'f(N::E)' is ambiguous
	return 0;
}


修改主函数代码为:

int main() {
	void f(N::E);
	::f(N::e1);
	f(N::e1);
	return 0;
}
输出:

::f(N::E) is called!!!
::f(N::E) is called!!!


int main() {
	using N::f;
	::f(N::e1);
	f(N::e1);
	return 0;
}
输出:

::f(N::E) is called!!!
N::f(N::E) is called!!!

Done!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值