C++必知必会之(25)实参相依的查找

1、实参相依的查找ADL:

当查找一个函数调用表达式中的函数名字时,编译器也会到“包含函数调用实参的类型”的名字空间中检查。

例如:

namespace org_semantics  {

      class X  { .... };

       void f ( const X & );

       void g ( X * );

       X operator + ( const X &, const X &);

       class String {   ....   };

       std::ostream operator << ( std::ostream &,  const String & );

}

//.....

int g ( org_semantics::X * );

void aFunc( )   {

     org_semantics::X  a;

     f ( a);                  //调用org_semantics::f

     g ( a);                //错误,调用具有歧义

     a = a + a;            //调用org_semantics::operator+

}

普通的查找是不会发现函数org_semantics::f的,因为它被嵌套在一个名字空间内,并且对f的使用需要以该名字空间的名字加以限定。

然而,由于实参a的类型被定义于org_semantics名字空间中,因此,编译器也会到该名字空间中检查候选函数。


本例中,程序员本来以为编译器会发现全局的g,但由于实参的类型是org_sematics::X *,因此该名字空间内的g成了候选函数之一,从而导致这个调用有歧义。

即使对g的调用导致了两个候选函数参与重载解析,::g实际上也并未重载org_sematics::g,因为它们不是声明于同一个作用域中的(参考重载与重写并不同)。

ADL是关于函数如何被调用的一个属性,而重载是关于函数被如何声明的一个属性。


2、可以看到ADL在对重载操作符的中缀调用中发挥作用,例如在aFunc中对operator + 的调用。

在这里,中缀表达式a+a等价于operator+( a,a),ADL将会在org_sematics名字空间中发现重载的operator+。


3、实际上,好多人广泛地应用了ADL但没意识到这点。考虑如下对<iostream>的常见使用:

org_sematics::String name( " Qwan" );

std::cout<<" Hello"<<name;

本例中,对operator<<的第一个使用(即最左边那一个),极有可能调用的是类模版std::basic_ostream的一个成员函数,而第二个则是对位于org_semantics名字空间中重载的operator<<的非成员函数的调用。ADL自动的打理了这些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值