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真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
随机推荐
- Java多态(非常重要)
多态(多种形态)的定义 同一消息对不同类的对象做出的不同响应 种类 在程序设计中一般说多态都是运行时多态 多态施行的条件: 1满足继承关系 2父类引用指向子类对象(向上转型) 向上转型 向下转型(子类 ...
- C++类中this指针的理解
先要理解class的意思.class应该理解为一种类型,象int,char一样,是用户自定义的类型.用这个类型可以来声明一个变量,比如int x, myclass my等等.这样就像变量x具有int类 ...
- Python日志模块logging&JSON
日志模块的用法 json部分 先开一段测试代码:注意 str可以直接处理字典 eval可以直接将字符串转成字典的形式 dic={'key1':'value1','key2':'value2'} ...
- Linux集群之keepalive+Nginx
集群从功能实现上分高可用和负载均衡: 高可用集群,即“HA"集群,也常称作“双机热备”. 当提供服务的机器宕机,备胎将接替继续提供服务: 实现高可用的开源软件有:heartbeat.keep ...
- Keras处理已保存模型中的自定义层(或其他自定义对象)
如果要加载的模型包含自定义层或其他自定义类或函数,则可以通过 custom_objects 参数将它们传递给加载机制: from keras.models import load_model # 假设 ...
- c# 对象的深拷备
C# 引用类型对象在拷备时,一般有浅拷备与深拷备,浅拷备指向的是同一对象的引用地址,一个对象的修改必然会影响另一个对象,而深拷备是直接拷备对象的内容,而不是引用,拷备后的对象拥有新的引用,这里主要介绍 ...
- 单链表查找第i个节点
#include<stdio.h> #include<string.h> #include<stdlib.h> typedef struct Node { char ...
- gentoo emacs 中文输入法 呼出
最近在另外一台电脑上面安装 gentoo和 emacs,但是碰到奇怪的问题,在旧电脑上面,可以使用 ctrl + space 呼出输入法,而新电脑只能触发 复制功能. 经过在网上查找和两台电脑之间的对 ...
- List转Json函数
public string ObjectToJson<T>(string jsonName, IList<T> IL) { StringBuilder Json = new S ...
- [PAClient Error] Error: E4356 File does not exist armv7
[PAClient Error] Error: E4356 File does not exist: /Users/tt/PAServer/scratch-dir/Administrator-snIO ...