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;
}

一些示例代码

 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 

原文地址:https://www.cnblogs.com/itdef/p/4370198.html