boost学习 泛型编程之traits 学习
traits使用的场景一般有三种 分发到不同处理流程 解决C++代码中某些无法编译的问题
比如一个图书馆的代码,接受书籍并收入到不同类别中
template<class T> // T表示接受的是何种书籍
void AcceptBooks(T books)
{
... //do something
};
我们有不同书籍 历史类书籍和计算机类书籍
struct history_tag{}; //这只是个空类,目的是激发函数重载
struct computer_tag{}; //同上
class HistoryBooks
{
public:
// 类型(身份)标志,表示这是历史类书籍,
// 如果是历史类则为typedef history_tag bookType;
typedef history_tag bookType;
};
class ComputerBooks
{
public:
typedef computer_tag bookType;
};
然后在接受书籍的代码里,对于不同类型的书籍进行不同处理
// 第二个参数为无名参数,只是为了激发函数重载
template<typename T>
void Accept(T& t,computer_tag)
{
std::cout << "accept computer books" << std::endl;
}
template<typename T>
void Accept(T& t,history_tag)
{
std::cout << "accept history books" << std::endl;
}
于是先前的AcceptBooks函数可以改写如下:
template<typename T>
void AcceptBooks(T& t)
{
// 无论是accept 历史书籍还是计算机书籍,根据不同的type 进入到不同的accept函数中去了
typedef typename T::bookType bookType;
Accept(t,bookType());
}
当然 进行一些必要的封装 看起来就更像样子了
template<typename T>
struct BooksTraits
{
typedef typename T::bookType bookType;
};
accept函数就写成这样
Accept(t, typename BooksTraits<T>::bookType());
完整代码如下:
#include <iostream>
struct history_tag{}; //这只是个空类,目的是激发函数重载
struct computer_tag{}; //同上
class HistoryBooks
{
public:
typedef history_tag bookType;
};
class ComputerBooks
{
public:
typedef computer_tag bookType;
};
template<typename T>
void Accept(T& t,computer_tag)
{
std::cout << "accept computer books" << std::endl;
}
template<typename T>
void Accept(T& t,history_tag)
{
std::cout << "accept history books" << std::endl;
}
// template<typename T>
// void AcceptBooks(T& t)
// {
// typedef typename T::bookType bookType;
// Accept(t,bookType());
// }
template<typename T>
struct BooksTraits
{
typedef typename T::bookType bookType;
};
template<typename T>
void AcceptBooks(T& t)
{
Accept(t, typename BooksTraits<T>::bookType());
}
int _tmain(int argc, _TCHAR* argv[])
{
ComputerBooks cb;
HistoryBooks hb;
AcceptBooks(cb);
AcceptBooks(hb);
return 0;
}
一些示例代码
// 123.cpp: 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <type_traits>
#include <iostream> //=======================================================
// is array
template<typename T>
struct is_array {
static const bool value = false;
}; template<typename T,size_t N>
struct is_array < T[N] > {
static const bool value = true;
};
//========================================================= //===========================================================
//is class
typedef char(&yes_type)[]; // sizeof(yes_type)==1
typedef char(&no_type)[]; // sizeof(no_type)==2 template<typename T>
struct is_class_impl {
template<typename U>
static
yes_type is_class_tester(void(U::*)(void)); template<typename U>
static
no_type is_class_tester(...);
static const bool value = (sizeof(is_class_tester<T>()) == sizeof(yes_type));
}; template<typename T>
struct is_class
{
// 所有实现都在is_class_imp中
static const bool value = is_class_impl<T>::value;
}; class testA {};
//============================================================== //============================================================
//is member function pointer //================================================= int main()
{
std::cout << is_array<int>::value << std::endl;
std::cout << is_array<int[]>::value << std::endl;
std::cout << is_array<int[]>::value << std::endl;
std::cout << is_class<int>::value << std::endl;
std::cout << is_class<testA>::value << std::endl;
return ;
}
至于刘未鹏(地址见文章最后参考列表)
所说的traits 用于效率一说 我觉得也算是分发到不同处理流程中的一种使用方法。
解决C++代码中某些无法编译的问题 则是说使用traits避开一些问题
比如引用的引用。
参考:
1 boost源码剖析之:泛型编程精灵type_traits(rev#2) http://blog.csdn.net/pongba/article/details/83828
boost学习 泛型编程之traits 学习的更多相关文章
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- C#可扩展编程之MEF学习笔记(三):导出类的方法和属性
前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经提供 ...
- C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import)
上一篇学习完了MEF的基础知识,编写了一个简单的DEMO,接下来接着上篇的内容继续学习,如果没有看过上一篇的内容, 请阅读:http://www.cnblogs.com/yunfeifei/p/392 ...
- C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo
在文章开始之前,首先简单介绍一下什么是MEF,MEF,全称Managed Extensibility Framework(托管可扩展框架).单从名字我们不难发现:MEF是专门致力于解决扩展性问题的框架 ...
- C#可扩展编程之MEF学习
MEF系列文章: C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import) C#可扩展编程之MEF学习 ...
- c# .Net并行和多线程编程之Task学习记录!
任务Task和线程Thread的区别: 1.任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行. 2.任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线 ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶(转)
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻(转)
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
随机推荐
- dll文件32位64位检测工具以及Windows文件夹SysWow64的坑【转发】
原文地址:http://www.cnblogs.com/hbccdf/archive/2014/03/09/3590916.html 自从操作系统升级到64位以后,就要不断的需要面对32位.64位的问 ...
- redux & react-redux
在vue中,可以使用vuex进行数据管理,在react中,可以使用redux进行数据管理.redux主要由Store.Reducer和Action组成: Store:状态载体,访问状态.提交状态.监听 ...
- springboot 的war包在Tomcat中启动失败
springboot 默认是通常是打包成jar的,里面会内置一个tomcat容器 有时候我们需要使用以前打成war包的方式部署到对应的tomcat中, 具体springboot 怎么从jar改成war ...
- MySQL SQL审核平台 inception+archer2.0(亲测)
docker run -d --privileged -v `pwd`/archer_data:/data -p 9306:3306 --name archer --hostname archer - ...
- 用kettle从mysql中使用存储过程读取数据写入到sqlserver数据库
1.mysql存储过程,可以实现动态表读取,满足较为复杂的业务逻辑 DROP PROCEDURE if exists p_get_car_trace; delimiter // CREATE PROC ...
- WM消息对应的Message消息中的Lparam和WParam
具体的消息表示: 1. WM_PAINT消息,LOWORD(lParam)是客户区的宽,HIWORD(lParam)是客户区的高 2. 滚动条WM_VSCROLL或WM_HSCROLL消息,LOWOR ...
- DevExpress的42种窗体样式
在Winform环境下DevExpress标题栏皮肤 第一步:引用DLL文件,安装DevExpress后在引用>程序集>扩展: DevExpress.BonusSkins.v12.2.dl ...
- javascript常用工具类整理(copy)
JavaScript常用工具类 类型 日期 数组 字符串 数字 网络请求 节点 存储 其他 1.类型 isString (o) { //是否字符串 return Object.prototype.to ...
- Android仿淘宝继续上拉进入商品详情页的效果,使用双Fragment动画切换;
仿淘宝继续上拉进入商品详情页的效果,双Fragment实现: 动画效果: slide_above_in.xml <?xml version="1.0" encoding=&q ...
- 为 github markdown 文件生成目录(toc)
业务需要 在编写 github 项目时,有时候会编写各种 README.md 等 markdown 文件,但是 github 默认是没有目录的. 于是就自己写了一个小工具. markdown-toc ...