zoukankan      html  css  js  c++  java
  • 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 

  • 相关阅读:
    mongodb修改bindIp和启动关闭
    把eclipse上的web项目导入IDEA
    项目重构也许更好——《梦断代码》读后感
    安卓记账本开发——数据库创建和数据测试
    开源的魅力——《梦断代码》读后感
    GitHub 网站上不去/加载慢/加载不全 解决办法
    安卓记账本开发——适配器编写和测试
    上传和下载
    cookie
    分页sql
  • 原文地址:https://www.cnblogs.com/itdef/p/4370198.html
Copyright © 2011-2022 走看看