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());

 

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#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;
}

 

一些示例代码

复制代码
 1 // 123.cpp: 定义控制台应用程序的入口点。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include <type_traits>
 6 #include <iostream>
 7 
 8 //=======================================================
 9 // is array
10 template<typename T>
11 struct is_array {
12     static const bool value = false;
13 };
14 
15 template<typename T,size_t N>
16 struct is_array < T[N] > {
17     static const bool value = true;
18 };
19 //=========================================================
20 
21 //===========================================================
22 //is class
23 typedef char(&yes_type)[1]; // sizeof(yes_type)==1
24 typedef char(&no_type)[2]; // sizeof(no_type)==2
25 
26 template<typename T>
27 struct is_class_impl {
28     template<typename U>
29     static 
30         yes_type is_class_tester(void(U::*)(void));
31     
32     template<typename U>
33     static 
34         no_type is_class_tester(...);
35     static const bool value = (sizeof(is_class_tester<T>(0)) == sizeof(yes_type));
36 };
37 
38 template<typename T>
39 struct is_class
40 {
41     // 所有实现都在is_class_imp中
42     static const bool value = is_class_impl<T>::value;
43 };
44 
45 class testA {};
46 //==============================================================
47 
48 //============================================================
49 //is member function pointer
50 
51 
52 
53 
54 //=================================================
55 
56 
57 int main()
58 {
59     std::cout << is_array<int>::value << std::endl;
60     std::cout << is_array<int[]>::value << std::endl;
61     std::cout << is_array<int[10]>::value << std::endl;
62     std::cout << is_class<int>::value << std::endl;
63     std::cout << is_class<testA>::value << std::endl;
64     return 0;
65 }
View Code
复制代码

 

至于刘未鹏(地址见文章最后参考列表)

所说的traits 用于效率一说 我觉得也算是分发到不同处理流程中的一种使用方法。

 

解决C++代码中某些无法编译的问题 则是说使用traits避开一些问题

比如引用的引用。

 

 

参考:

1  boost源码剖析之:泛型编程精灵type_traits(rev#2) http://blog.csdn.net/pongba/article/details/83828 

posted on   itdef  阅读(367)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示