//############################################################################
/*
* Koenig Lookup / Argument Dependent Lookup (ADL)
*/ // 例1: 什么是Koenig查找
namespace A
{
struct X {};
void g( X ) { cout << " calling A::g() \n"; }
} // void g( X ) { cout << " calling A::g() \n"; } //如果再加一个函数,会编译不过 int main() {
A::X x1;
A::g(x); //正常
g(x1); // 移除A::并不会报错,会到实参所在的命名空间查找
} // 例2:
class C {
public:
struct Y {};
static void h(Y) { cout << "calling C::h() \n"; }
}; int main() {
C::Y y;
h(y); // Error Koenig查找只对命名空间有效,对类无效
} // 例3:
namespace A
{
struct X {};
void g( X ) { cout << " calling A::g() \n"; }
} class B {
void g(A::X ) { cout << "calling B::g() \n" ; }
}; class C : public B {
public:
void j() {
A::X x;
g(x);
}
}; int main() {
C c;
c.j(); //没有歧义,先在类中查找,没找到再去global和Koenig查找
} // 名字隐藏的情况:命名空间的例子
namespace A
{
struct X {};
void g(X ) { std::cout << " calling A::g() \n"; } namespace C {
void g( ) { std::cout << "calling C:g() \n" ; }
void j() {
//using A::g;
g(8); //编译不过,名字遮蔽
X x;
g(x); //Koenig原则同样有效
}
}
} int main() {
A::C::j();
} /*
* 名字查找顺序
*
* 命名空间:
* 当前作用域 => 外面一层作用域 => ... => 全局作用域
*
* 要覆写顺序:
* 1. 使用限定符或者using声明
* 2. Koenig lookup
*
* 类:
* 当前类作用域 => 父类作用类 => ... => 全局域
*
* 要覆写顺序::
* - 使用限定符或者using声明
*
*
* 名字隐藏
* 当高层作用域定义了和低层作用域相同名字的函数
*/ /*
* 为啥要有Koenig Lookup?
*/ // 例1:
namespace A
{
struct X {};
void g( X ) { cout << " calling A::g() \n"; }
void g( ) { cout << " calling A::g() \n"; }
} int main() {
A::X x1;
g(x1); // Koenig Lookup, or Argument Dependent Lookup (ADL)
g(); // Error
} /*
* 1. 实际原因
*/ std::cout << "Hi.\n"; // 这里的数据运算符会调用 std::operator<<,而不用显式指定 std::cout std::<< "Hi.\n"; // 如果没有Koenig查找,要写成这种形式,编译不过
std::operator<<(std:cout, "Hi,\n"); //正确的写法 /*
* 2. 理论原因:
* -- 什么是类的接口?
*/ namespace A
{
class C {
public:
void f() = 0;
void g() = 0;
};
void h(C); //是C的接口的一部分
ostream& operator<<( ostream&, const C& ); //是C的接口的一部分
}
void j(C); //不就是C的接口的一部分 /*
* 类的定义:
* 类是描述一组数据以及操作这些数据的函数的集合。
*/ /*
* 工程上的原则:
* 1. 对C类进行操作且跟C在同一个命名空间的函数是C的接口的一部分
* 2. 所以作为C的接口的一部分的函数需要在同一个命名空间下
*/ A::C c;
c.f(); //可以直接调用
h(c); //可以直接调用 namespace A {
class C {};
int operator+(int n, A::C) { return n+1; } //如果放在外面可能会出现问题,万一std命名空间中定义了其他函数,就不会找到这个函数
} int main()
{
A::C arr[3];
std::accumulate(arr, arr+3, 0); // return 3
} // 定义在C++标准库<numeric>
namespace std {
template <class InputIterator, class T>
T accumulate ( InputIterator first, InputIterator last, T init )
{
while ( first!=last )
init = init + *first++;
return init;
}
}

C++进阶--Koenig lookup 依赖于实参的名字查找的更多相关文章

  1. MVC进阶之路:依赖注入(Di)和Ninject

    MVC进阶之路:依赖注入(Di)和Ninject 0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类, ...

  2. Java进阶(三十九)Java集合类的排序,查找,替换操作

    Java进阶(三十九)Java集合类的排序,查找,替换操作 前言 在Java方向校招过程中,经常会遇到将输入转换为数组的情况,而我们通常使用ArrayList来表示动态数组.获取到ArrayList对 ...

  3. ASP.NET MVC进阶之路:依赖注入(Di)和Ninject

    0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点.在程序运行过程中,客户 ...

  4. scrapy技术进阶-URL路径依赖

    方法1: #!/usr/bin/python # -*- coding: gbk -*- import time from scrapy.spider import BaseSpider from s ...

  5. ADL & 实参相依的查找 & 成员与非成员的查找

    也就是会根据实参,所处在的名字空间,来查找对应名字空间里面的函数. 对于<<也是常见的场景,会根据实际要打印出来的下一个操作数,来决定调用哪个命名空间里面的函数. 注意,不同命名空间里面的 ...

  6. Filter Lookup Editor Data Source 筛选器查找编辑器数据源

    In this lesson, you will learn how to filter the data displayed by a lookup editor. This editor is s ...

  7. [C#进阶系列]专题二:你知道Dictionary查找速度为什么快吗?

    一.前言 在之前有一次面试中,被问到你了解Dictionary的内部实现机制吗?当时只是简单的了问答了:Dictionary的内部结构是哈希表,从而可以快速进行查找.但是对于更深一步了解就不清楚了.所 ...

  8. underscore.js依赖库函数分析二(查找)

    查找: 在underscore.js封装了对dom查找的操作,find()和filter()函数,find()函数的查找操作是返回首个与条件相符的元素值,filter()函数是找到与条件相符的所有元素 ...

  9. Informatica 常用组件Lookup缓存之二 使用永久查找高速缓存

    可以将"查找"转换配置为使用非永久或永久高速缓存.基于"查找高速缓存永久"属性的会话成功后,PowerCenter 将保存或删除查找高速缓存文件. 如果查找表在 ...

随机推荐

  1. ::before和::after伪元素

    伪元素的意思就是,元素不是在DOM中生成的,而是在浏览器渲染CSS的时候画上去的,所以在浏览器查看元素上是看不到伪元素的HTML结构的. before 和 after 顾名思义就是附着在元素前后的伪元 ...

  2. (20)jQuery的文档操作(创建,添加、设置样式和删除等)

    <!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>jq ...

  3. random(随机模块)

    程序中有很多地方需要用到随机字符,比如登录网站的随机验证码,通过random模块可以很容易生成随机字符串 >>> random.randrange(1,10) #返回1-10之间的一 ...

  4. Linux命令速查手册

    Others make 通过外部编译器的,比如linux中的gcc集来编译源码 获取Makefile文件的命令触发编译 curl -X GET/POST -I 获取head curl有cache 查看 ...

  5. uboot2014.10移植(一)

    最新有点时间,所以想折腾点东西,于是拿起了几年前的TQ2440玩玩,下载了uboot2014.10版本,准备移植到板子上去,没想到折腾环境都折腾了一下午. 1.工具链安装 我的工具链直接用命令安装的: ...

  6. 利用 httpmodule 强制所有页面使用同一基类

    public class OMSPageChecker : IHttpModule { public void Dispose() { } public void Init(HttpApplicati ...

  7. day5 python学习

    本日主要讲了列表的一些操作 1.列表的增 ret=['wang','taibai','alxe','ritian'] ret.append("wusir") print(ret) ...

  8. keydown,keypress,keyup三者之间的区别

    最近看了Javascript高级教程中对过滤输入的介绍,想实现比如电话号码中不能包好非数值的字符,而相应文本中插入字符的操作是keypress事件,所以就想通过阻止这个事件的默认事件行为来阻止这个事件 ...

  9. php编译GD库 JPEG Support

    Fatal error: Call to undefined function imagecreatefromjpeg() http://chen498402552-163-com.iteye.com ...

  10. toString() 和 toLocaleString() 的区别

    toString() 和 toLocaleString() 的区别 table th:nth-of-type(4) { width: 400px; } 区别项 toString() toLocaleS ...