C++11 TypeList 妙用
源码展示:
#include <iostream> using namespace std; template <typename ... Args> struct typelist; typedef typelist <int ,short ,double ,long ,float> defaultPolicys; template <typename A, typename B> struct concat; template <typename... A, typename... B>
struct concat<typelist<A...>, typelist<B...> >
{
typedef typelist<A..., B...> type;
}; template<typename T, typename... TList>
struct concat<typelist<TList...>, T >
{
typedef typelist<TList..., T> type;
}; template<typename T, typename... TList>
struct concat< T, typelist<TList...> >
{
typedef typelist<T, TList...> type;
}; template <typename T ,int I, typename K= defaultPolicys> struct replace; template <typename T, int I, typename H,typename ...Tail> struct replace<T,I,typelist<H,Tail...>>
{
typedef typename concat<H, typename replace<T, I-, typelist<Tail...>>::type>::type type;
}; template <typename T,typename H,typename... Tail> struct replace<T,,typelist<H,Tail...>>
{
typedef typelist<T,Tail...> type;
}; template <typename T ,int I> struct Custom
{
const static int index = I;
typedef T newType;
}; template <typename ...> struct CEO; template <> struct CEO<>
{
typedef defaultPolicys myPolicys;
}; template <typename T> struct CEO<T>
{
typedef typename replace<typename T::newType,T::index>::type myPolicys;
};
//template <typename T,typename U> struct CEO<T,U>{ typedef typename replace<typename U::newType,U::index,typename CEO<T>::myPolicys>::type myPolicy;}; template <typename T,typename ... Tail> struct CEO<T,Tail...>
{
typedef typename replace<typename T::newType,T::index,typename CEO<Tail...>::myPolicys>::type myPolicys;
}; int main()
{ typedef typelist <int ,short ,double ,long ,float> five;
typedef typelist <int ,short ,string, char ,string> fives;
if(is_same<typename CEO<>::myPolicys,five>::value)cout<<"..."<<endl;
if(is_same< CEO< Custom<string,>,Custom<char,>,Custom<string,> > ::myPolicys,fives>::value)cout<<"..."<<endl; return ; }
template <typename ... Args> struct typelist; typelist声明
template <typename A, typename B> struct concat; 连接任意类型至typelist头或尾部声明
template <typename... A, typename... B>
struct concat<typelist<A...>, typelist<B...> >
{
typedef typelist<A..., B...> type;
}; 连接两个typelist偏特化定义 template<typename T, typename... TList>
struct concat<typelist<TList...>, T >
{
typedef typelist<TList..., T> type;
}; 将类型连接至typelist尾部偏定义 template<typename T, typename... TList>
struct concat< T, typelist<TList...> >
{
typedef typelist<T, TList...> type;
}; 将类型连接至typelist头部偏特化定义
template <typename T ,int I, typename K = defaultPolicys> struct replace; 用类型T替换K=typelist的I位置类型的声明
template <typename T, int I, typename H,typename ...Tail> struct replace<T,I,typelist<H,Tail...>>
{
typedef typename concat<H, typename replace<T, I-1, typelist<Tail...>>::type>::type type;
}; 偏特化定义,递归入口 template <typename T,typename H,typename... Tail> struct replace<T,0,typelist<H,Tail...>>
{
typedef typelist<T,Tail...> type;
}; 偏特化定义,递归出口
template <typename T ,int I> struct Custom
{
const static int index = I;
typedef T newType;
}; 用于自定义类型
template <typename ...> struct CEO; CEO:Policys的执行者 template <> struct CEO<>
{
typedef defaultPolicys myPolicys; CEO<>拥有默认的Policys
}; template <typename T> struct CEO<T>
{
typedef typename replace<typename T::newType,T::index>::type myPolicys;
}; 自定义单个Policy的偏特化定义
//template <typename T,typename U> struct CEO<T,U>{ typedef typename replace<typename U::newType,U::index,typename CEO<T>::myPolicys>::type myPolicy;}; template <typename T,typename ... Tail> struct CEO<T,Tail...>
{
typedef typename replace<typename T::newType,T::index,typename CEO<Tail...>::myPolicys>::type myPolicys;
}; 自定义多个Policys的偏特化定义
使用如下代码初步测试:
CEO< Custom<string,2>,Custom<char,3>,Custom<string,4> > ::myPolicys
myPolicys 类型为 typelist<int ,short ,string ,char ,string>
----------------------------------------------------------------------------------------------------------------------------------------
这段代码有什么用?
假设在typelist中,每一个类型拥有一个静态的函数,若如此CEO<>拥有一套默认的函数。
CEO<Custom<xType,xIndex>> ,将替换掉某个默认的函数行为。
这听起来有点像模板方法模式,但我们使用是静多态,并没有使用继承和虚函数机制。
而且用户使用也相当容易,并且代码更容易扩展,如果需要更改默认的Policys,只需扩充默认typelist即可。 在《C++ Template》 一书中,继承与模板那一章的第一节,讲述的是如何使用多继承和模板完成上述功能,而在《C++ 设计新思维》中讲到了typelist技术,而如今C++14提供可变长模板参数。
结合此三项,初步实现上述代码。文章标题 言为妙用,实不敢当,有兴趣的同学,可以继续深入研究,在此抛砖引玉。 转载请表明出处,谢谢合作
C++11 TypeList 妙用的更多相关文章
- 地区sql
/*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...
- 使用c++11改写loki的TypeList
最近看了C++11的一些特性,最感兴趣的是可变模板参数,自动类型推断和匿名函数. Loki中的TypeList,是需要递归定义的,并且需要一个NullType作为尾节点. 可变模板参数使得实现Type ...
- 妙味课堂:JavaScript初级--第11课:字符串、查找高亮显示
1.数字字母 Unicode 编码 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content- ...
- 妙味css3课程---1-1、css中自定义属性可以用属性选择器么
妙味css3课程---1-1.css中自定义属性可以用属性选择器么 一.总结 一句话总结:可以的. 1.如何实现用属性选择器实现a标签根据href里面含有的字段选择背景图片? p a[href*=te ...
- c++11 关于typelist的foreach
建好一个typelist,其中都是类型信息而已,很重要的一个应用,循环迭代干些事情. 看了下boost的for_each实现,用我自己的typelist,大概代码如下: template<typ ...
- 泛化之美--C++11可变模版参数的妙用
1概述 C++11的新特性--可变模版参数(variadic templates)是C++11新增的最强大的特性之一,它对参数进行了高度泛化,它能表示0到任意个数.任意类型的参数.相比C++98/03 ...
- 泛化之美 —— C++11 可变参数模板的妙用
概述 首先这篇文章出自博客园作者:[qicosmos ],我对本文的实例代码进行了学习.思考和整理纠正,理清了文章的全部细节,觉得这是一篇让我受益匪浅的文章.之所以会接触「可变参数模板」这部分的内容, ...
- X86逆向11:F12暂停法的妙用
本节课将介绍F12暂停法的使用技巧,F12暂停法的原理其实很简单,当我们点击OD中的暂停按钮时,OD会将当前的堆栈状态保存起来,并暂停当前窗体的线程执行,直到我们点击运行按钮OD才会唤醒全部线程并继续 ...
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
随机推荐
- Visual C++中MFC消息的分类
Visual C++中MFC消息的分为三类:标准(窗口)消息.命令消息.控件消息. 1.标准(窗口)消息:窗口消息一般与窗口内部运作有关,如创建窗口,绘制窗口,销毁窗口,通常,消息是从系统发到窗口,或 ...
- python中的sum函数.sum(axis=1)
看起来挺简单的样子,但是在给sum函数中加入参数.sum(a,axis=0)或者是.sum(axis=1) 就有点不解了 在我实验以后发现 我们平时用的sum应该是默认的axis=0 就是普通的相加 ...
- asp.net mvc HtmlHelperExt EnumDropDownList
public static class HtmlHelperExt { public static MvcHtmlString EnumDropDownList<TEnum>(this H ...
- Lodash数组篇
概念简述 lodash 是一个类库 Lodash 通过降低 array.number.objects.string 等等的使用难度从而让 JavaScript 变得更简单 用法 let _ = re ...
- 轻量ORM-SqlRepoEx (八)MySQL、Sql Service 迁移
数据库变更在编程应用中是常的,MySQL.Sql Service之间的数据迁移更为常见,在 SqlRepoEx2.0DemoForAspCore中演示了,这种数据库之间切换时SqlRepoEx是如何的 ...
- Swiper2和Swiper3区别详解与兼容IE8/IE9
最近项目一些网站项目想到用Swiper3来制作响应式,但是发现IE9都不兼容, 而swiper2版本又少一个breakpoints参数 做响应式脚本非常不方便,于是想到新版的浏览器用3 ,iE9和以 ...
- Linux 实时查看进程网络的使用情况
一行代码实现 linux 指定进程网络的使用情况 pid=4203;count=0;while true;do info2=`sed -n '4,100p' /proc/$pid/net/dev |a ...
- 生产环境MySQL数据库集群MHA上线实施方案
生产环境MySQL数据库集群MHA上线实施方案 一.不停库操作 1.在所有节点安装MHAnode所需的perl模块(需要有安装epel源) yum install perl-DBD-MySQL -y ...
- Linux中将端口(80)重定向
在Linux中直接指定命令: iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 其中80为要访问的端 ...
- JQuery制作网页—— 第六章 jQuery选择器
1.jQuery选择器:jQuery选择器类似于CSS选择器,用来选取网页中的元素. Eg:$("h3").css("background",&qu ...