泛型编程之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;

}

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

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

 

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

比如引用的引用。

 

 

参考:

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

你可能感兴趣的:(traits)