关闭

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

标签: C++namespacestring对象basic
650人阅读 评论(0) 收藏 举报
分类:

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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:199259次
    • 积分:4436
    • 等级:
    • 排名:第6989名
    • 原创:273篇
    • 转载:42篇
    • 译文:0篇
    • 评论:0条
    博客专栏