//############################################################################
/*
* 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. JS中数据类型的判断

    typeof 使用 : var n = "hello"; console.log(typeof n); console.log(typeof(n));

  2. 第十三次CCF第四题 1803——04 博弈

    我又写了一个简洁版的2.0: 可以作为博弈搜索树的模板  : https://www.cnblogs.com/xidian-mao/p/9389974.html 废话ps: 开始觉得这是一道简单得博弈 ...

  3. PTA——各位数之和

    PTA 7-28 求整数的位数及各位数字之和 我的程序: #include<stdio.h> #include<math.h> int main(){ ,t; scanf(&q ...

  4. NET Core + Ocelot + IdentityServer4 + Consul

    .NET Core + Ocelot + IdentityServer4 + Consul 基础架构实现 先决条件 关于 Ocelot 针对使用 .NET 开发微服务架构或者面向服务架构提供一个统一访 ...

  5. mysql 常用函数-locate 和 instr 和 regexp

    ★1 -- 表级锁 情况SHOW STATUS LIKE 'table%';-- 行级锁 情况SHOW STATUS LIKE 'innodb_row_lock%'; -- 进程列表SHOW PROC ...

  6. gxx -L和/etc/ld.so.conf的理解

    编程之路刚刚开始,错误难免,希望大家能够指出. 今天编了个动态库,然后自己测试了一下. 忘记设置程序运行时系统搜索库的路径发生错误: 忘记设置程序编译的时候 -L 指定路径报的错误: -L : 告诉程 ...

  7. How_Require_Extensions_Work

    Why Doing require extensions correctly is essential, because: Users should be able to install multip ...

  8. laya的那些坑

    游戏运行在chrome里面 听不见声音 游戏运行在chrome里面  听不见声音:其它浏览器可以听见声音开发者模式提示如下: The AudioContext was not allowed to s ...

  9. 高级java必会系列一:常用线程池和调度类

    众所周知,开启线程2种方法:第一是实现Runable接口,第二继承Thread类.(当然内部类也算...)常用的,这里就不再赘述. 一.线程池 1.newCachedThreadPool (1)缓存型 ...

  10. C++Builder XE7 up1 简单测试

    很久没用BCB了, 新装了BCBXE7up1试试了,发现有点找不到北了,好像与BCB6的一些默认设置项不一样,编译了一个空APP,提示找不到bpl 和 dll. 设置为不带包编译后,还是提示DLL找不 ...