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的路由系统. 例子
随机推荐
- mybatis全局配置文件
一.properties:引入外部配置文件 1.resource :引入类路径下的全局配置文件,例如:<properties resource="conf/dbconfig.prope ...
- 简单使用idea Spring Boot搭建项目
第一步:使用Spring Initializr创建 第二步:项目配置 第三步:选择项目需要的依赖 第五步: ok 创建完成,修改仓库 maven{ url 'http://maven.aliyun.c ...
- diogo谈框,仿prompt()方法布局
展示效果: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- HDU 4864 Task(经典贪心)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=4864 Task Time Limit: 4000/2000 MS (Java/Others) M ...
- react系列(五)在React中使用Redux
上一篇展示了Redux的基本使用,可以看到Redux非常简单易用,不限于React,也可以在Angular.Vue等框架中使用,只要需要Redux的设计思想的地方,就可以使用它. 这篇主要讲解在Rea ...
- Null 值对索引排序的影响案例一则
--原SQL 语句如下:select * from (select tmp_tb.*, ROWNUM row_id from (select wpid, customer_id, customer_n ...
- 【oracle笔记4】存储过程
存储过程是一组为了完成特定功能的sql语句集,存储在数据库中,经过一次编译后再次调用不需要编译.用户通过指定存储过程的名字来执行它. 基本语法: create or replace procedure ...
- 搭建Extjs框架(二)
搭建Extjs 框架 二.编写入口文件 app.js,配置extjs 组件\视图文件路径 并将app.js引入index.html 在app.js中指定一些文件的路径,Extjs页面的起始 ...
- 737 MAX 8-Think
波音 737 MAX 8的事故,凸显传感器数据在失真的情况下,软件系统需要如何设计的问题:这点感觉波音那么大的公司,不应该不会没有考虑到. 正常来说传感器给出错误的数据,通常是计算出错误的结果,就像做 ...
- 如何优雅的使用C语言绘制一只小猪佩奇
今天我们来用C语言画一只小猪佩奇---社会.社会....在画小猪佩奇之前,我们先使用带符号的距离长 (signed distance field,SDF) 来画一个圆形. 使用这个方法表示形状,但是这 ...