作者 | 庇护所之主 编辑 | 自动驾驶之心
原文链接:https://www.zhihu.com/question/21376384/answer/3459052295
点击下方
卡片
,关注“
自动驾驶之心
”公众号
>>
点击进入→
自动驾驶之心
『
BEV感知
』
技术交流群
本文只做学术分享,如有侵权,联系删文
自动驾驶之心+自动驾驶之薪+具身智能之心知识星球 | 双十一活动限时7折
微软的proxy库
只有一个头文件,不到一千行的代码量
初见只觉神奇,不用继承就可以做运行时的各种抽象
用过一段时间之后感觉深不可测,小小的库完整实现了运行时多态所需的各种设施,包括重载、异常、反射等等,全方位碾压虚函数
初看代码感觉逻辑密度极高,有种指点江山的既视感
细品代码发现有很多匪夷所思的高难度体操,离奇而不失优雅
放几个片场给大家品鉴
片场1
template class R, class O, class... Is>
struct recursive_reduction : std::type_identity {};
template class R, class O, class I, class... Is>
struct recursive_reduction
: recursive_reduction::type, Is...> {};
template class R, class O, class... Is>
using recursive_reduction_t = typename recursive_reduction::type;
这简单几行代码就实现了任意个数类型的自动化推导。代码中总共有两处应用,其中一处实现了把任意嵌套的类似tuple的类型展平并去重:
template struct flat_reduction : std::type_identity {};
template
struct flat_reduction_impl : recursive_reduction {};
template
requires(!is_tuple_like_well_formed() && (!std::is_same_v && ...))
struct flat_reduction<:tuple>, I>
: std::type_identity<:tuple>> {};
template requires(is_tuple_like_well_formed())
struct flat_reduction : instantiated_t {};
其中 instantiated_t 可以用一个类似 tuple 的类型来实例化一个给定的类模板:
template class T, class TL, class Is, class... Args>
struct instantiated_traits;
template class T, class TL, std::size_t... Is,
class... Args>
struct instantiated_traits, Args...>
{ using type = T...>; };
template class T, class TL, class... Args>
using instantiated_t = typename instantiated_traits<
T, TL, std::make_index_sequence<:tuple_size_v>>, Args...>::type;
有了这些基础设施,这个库就可以在编译时接受任意嵌套组合的抽象了!
例如:
PRO_DEF_FACADE(F1, std::tuple);
PRO_DEF_FACADE(F2, std::tuple>);
PRO_DEF_FACADE(F3, std::tuple<:pair>, std::pair>);
在编译时是等价的!
这就意味着以前使用虚函数时需要极力避免的菱形继承在使用这个库的时候完全不是问题,因为这个信息根本不会被编译到程序中!
片场2