//############################################################################
/*
* 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. java-冒泡排序、选择排序、二分查找

    1.冒泡排序 public void bubbleSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { //外循环只需要比较a ...

  2. 在java中(==)的用法

  3. mac 终端光标在单词之间移动

    https://ruby-china.org/topics/1241#reply16 you can use :  option + b / f not  ctrl  + <- / ->

  4. C++中的智能指针、轻量级指针、强弱指针学习笔记

    一.智能指针学习总结 1.一个非const引用无法指向一个临时变量,但是const引用是可以的! 2.C++中的delete和C中的free()类似,delete NULL不会报"doubl ...

  5. C++中的const关键字学习笔记

    一.const引用 1. 例子一 #include <iostream> using namespace std; class sp { public: sp() {cout<< ...

  6. OFIFG fault when using DCO in MSP430

    The OFIFG flag always set in my recent MSP430 smoke device project. In this A sample hardware, there ...

  7. YUM安装调试以及命令具体解释

    背景,须要安装cacti,google了非常多安装资料.须要先yum安装一些准备lib包,比方snmp以及openssl等等. [root@mysqlvm2 ~]# yum install net-s ...

  8. css获取样式

    1)类似id.style.width:只能获取<div style="width:200px;">内联样式</div>里面style里的width,即内联样 ...

  9. HI35XX NVR

    NVR类型的:3515-3520-3531-3535-3536 后面的高端

  10. [转]Serializable接口与Externalizable接口区别

    被Serializable接口声明的类的对象的内容都将被序列化,如果现在用户希望自己指定序列化的内容,则可以让一个类实现Externalizable接口,此接口定义如下: public interfa ...