什么是ADL

ADL(Argument Dependent Lookup),参数依赖查找,明确的意思是依赖参数的函数查找,即对于函数调用,不仅会依照常规的名称查找规则,还会在函数参数所在的命名空间内查找

我们常用的 std::cout << "..." 其实就是一个 ADL 的例子,std::cout,查看一下 STL 的代码,它是

std::basic_ostream<char, std::char_traits<char>>

而这个类只定义了针对算术类型和指针类型的 operator<< 并没有定义针对 const char * 的版本,使用编译器的跳转功能跳转到 << 的调用,其实是

template<class _Traits>

std::basic_ostream<char, _Traits> operator<<(std::basic_ostream<char, _Traits> &, const char *)

也就是说这个调用其实等价于:

operator<<(std::cout, "...")//注意operator<<前并没有使用std::来指定查找位置

这个对于 std::operator<< 的调用能顺利解析而不会触发 '没有与操作数匹配的操作符' 错误,正是由于ADL发挥了作用:第一个参数 std::cout 所在的命名空间 std 被加入到对 operator<< 的查找空间内,从而匹配到针对 const char * 的 operator<<

ADL+模板

当函数参数是模板时,查找空间会扩展到参数模板所在的命名空间以及模板实参的命名空间:

折叠代码
namespace space
{
struct A{};
template<typename T> struct TpA{};
template<typename T, template<typename> class Tp>
void foo(Tp<T> &){}
}
template<typename T> struct TpB{};
space::TpA<int> tai;
foo(tai);//通过TpA找到foo
TpB<space::A> tba;
foo(tba);//通过A找到foo

根据模板实参自动选择调用函数

ADL+模板很容易就能实现根据模板实参调用不同函数的功能:

折叠代码
namespace spaceA
{
struct A{};
void foo(A &){}
}
namespace spaceB
{
struct B{};
void foo(B &){}
}
...
template<typename T> void dispatch(T &value)
{
foo(value);
}
spaceA::A a;
dispatch(a);//绑定到spaceA::foo(spaceA::A &)
spaceB::B b;
dispatch(b);//绑定到spaceB::foo(spaceB::B &)

只要约定好接口,dispatch函数就能根据实例化类型来调用,可以实现松散的代码结构,并且函数的绑定在编译期进行,继承体系也能实现相同的需求,但是函数的调用是运行时解析。可以根据实际情况决定选用哪种方案。

C++ ADL 与 模板的更多相关文章

  1. boost::swap

    boost::swap是对标准库里的std::swap的增强和泛化,为交换两个变量的值提供便捷的方法. 为了使用需包含头文件: #include <boost/swap.hpp> 原理 c ...

  2. c++11-17 模板核心知识(十三)—— 名称查找与ADL

    名称分类 名称查找 ordinary lookup ADL (Argument-Dependent Lookup) 官网的例子 ADL的缺点 在C++中,如果编译器遇到一个名称,它会寻找这个名称代表什 ...

  3. C++ template —— 实例化和模板实参演绎(四)

    本篇讲解实例化和模板实参演绎-------------------------------------------------------------------------------------- ...

  4. C++ template —— 模板中的名称(三)

    第9章 模板中的名称------------------------------------------------------------------------------------------ ...

  5. 参数依赖查找(ADL,Argument-dependent lookup)

    参数依赖查找(Argument-dependent lookup),又称 ADL 或 Koenig 查找,是一组于函数调用表达式查找非限定函数名的规则,包含对重载运算符的隐式函数调用.在通常非限定名称 ...

  6. C++ ADL

    即在一个名称作为调用运算符的左操作数时,并且这个名字是一个无限定名称时,在无限定查找到的名字集合中额外增加的一个规则使集合范围扩大(从而可以定位到其他一些限定名称),通常是用来保证定义在不同命名空间的 ...

  7. c++11-17 模板核心知识(十四)—— 解析模板之依赖型模板名称(.template/->template/::template)

    tokenization与parsing 解析模板之类型的依赖名称 Dependent Names of Templates Example One Example Two Example Three ...

  8. c++11-17 模板核心知识(十五)—— 解析模板之依赖型类型名称与typename Dependent Names of Types

    模板名称的问题及解决 typename规则 C++20 typename 上篇文章c++11-17 模板核心知识(十四)-- 解析模板之依赖型模板名称 Dependent Names of Templ ...

  9. Jade模板引擎让你飞

    写在前面:现在jade改名成pug了 一.安装 npm install jade 二.基本使用 1.简单使用 p hello jade! 渲染后: <p>hello jade!</p ...

  10. ABP入门系列(2)——通过模板创建MAP版本项目

    一.从官网创建模板项目 进入官网下载模板项目 依次按下图选择: 输入验证码开始下载 下载提示: 二.启动项目 使用VS2015打开项目,还原Nuget包: 设置以Web结尾的项目,设置为启动项目: 打 ...

随机推荐

  1. DeepSeek 不太稳定?那就搭建自己的 DeepSeek 服务

    概述 DeepSeek-R1 发布 DeepSeek 在 2025 年给我们送来一份惊喜,1 月 20 号正式发布第一代推理大模型 DeepSeek-R1.这个模型在数学推理.代码生成和复杂问题解决等 ...

  2. Opera打不开网页解决办法

    打开目录C:\Users\用户名\AppData\Roaming\Opera Software\Opera Stable 2.查找{"country":"CN" ...

  3. Top-N推荐算法 Top-N recommendation Algorithms

    引言 推荐算法是计算机专业中的一种算法,通过一些计算,能够推测用户喜欢的东西,在互联网环境中应用比较广泛.Top-N算法在生活中非常常见,比如学术论文推荐论文.音乐软件推荐歌曲等. 今天看到一篇名叫& ...

  4. CATIA许可证破解方法(CMD版)

    <<< catia的DS License Server Administration后不会自动弹出GUI界面,就需要使用CMD来破解安装许可证. <<< 1. ca ...

  5. jQuery ajax 文件上传 Request Headers 缺少 boundary

    原文地址: https://blog.jijian.link/2020-07-28/jquery-ajax-upload-file/ 一般上传方式 const file = document.getE ...

  6. 学习高可靠Redis分布式锁实现思路

    一.分布式锁的必要性 在单体应用时代,我们使用ReentrantLock或synchronized就能解决线程安全问题.但当系统拆分为分布式架构后(目前大多数公司应该不会只是单体应用了),跨进程的共享 ...

  7. Open-Sora 2.0 重磅开源!

    潞晨科技正式推出 Open-Sora 2.0 -- 一款全新开源的 SOTA 视频生成模型,仅 20 万美元(224 张 GPU)成功训练商业级 11B 参数视频生成大模型.开发高性能的视频生成模型通 ...

  8. 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!

    效果 来具体介绍之前先来看看效果. 使用C#构建了一个简单的MCP客户端,以下为运行这个简单客户端的截图,同样可以在Cline等其它的一些MCP客户端中玩耍. 创建一个数据库表: 获取数据库中的所有表 ...

  9. es6 export和export default的区别

    相同点 export 与 export default 均可用于导出常量.函数.文件.模块 可在其它文件或模块中通过import+(常量 | 函数 | 文件 | 模块)名的方式,将其导入,以便能够对其 ...

  10. MD5加密BASE64加解密

    MD5需要引入system.Hash,BASE64需要引入System.NetEncoding,这两个单元应该只有高版本的DELPHI IDE才有 (貌似XE5以上版本才有).如果是D7的话,找第三方 ...