代码改变世界

c++ template(10)类型函数

2013-04-25 14:14  Clingingboy  阅读(1292)  评论(0编辑  收藏  举报

 

一.sizeof模板化

#include <stddef.h>
#include <iostream>

template <typename T>
class TypeSize {
  public:
    static size_t const value = sizeof(T);
};

int main()
{
    std::cout << "TypeSize<int>::value = "
              << TypeSize<int>::value << std::endl;
}

二.获取容器元素类型

 

#include <vector>
#include <list>
#include <stack>
#include <iostream>
#include <typeinfo>

template <typename T> 
class ElementT;                    // primary template

template <typename T>
class ElementT<std::vector<T> > {  // partial specialization
  public:
    typedef T Type;
};

template <typename T>
class ElementT<std::list<T> > {    // partial specialization
  public:
    typedef T Type;
};

template <typename T>
class ElementT<std::stack<T> > {   // partial specialization
  public:
    typedef T Type;
};

template <typename T>
void print_element_type (T const & c)
{
    std::cout << "Container of "
              << typeid(typename ElementT<T>::Type).name()
              << " elements.\n";
}

int main()
{
    std::stack<bool> s;
    print_element_type(s);
}

通过定义一个内部变量来简化上述工作

 

template <typename C> 
class ElementT { 
public: 
    typedef typename C::value_type Type; 
}; 

标准库都定义了这样的类型

std::cout << "Container of "
    << typeid( std::stack<bool>::value_type).name()
    << " elements.\n";

通过此方法来简化模板参数数量.

原先原型:

template <typename T, typename C> 
T sum_of_elements (C const& c); 

利用上面的内部type简化参数数量

template<typename C> 
typename ElementT<C>::Type sum_of_elements (C const& c); 

三.确定一个对象是否是类类型

参考:http://www.cnblogs.com/mightofcode/archive/2013/04/07/3005849.html

#include <iostream>

template<typename T>
class IsClassT
{
    typedef char _One;
    typedef struct{char a[2];}_Two;
    template<typename T>
    static _One isClass(int T::* p);
    template<typename T>
    static _Two isClass(...);
public:
    enum { Yes = sizeof(isClass<T>(NULL))==sizeof(_One) };
    enum { No = !Yes };
     
};

class MyClass { 
}; 

struct MyStruct { 
}; 

union MyUnion { 
}; 

void myfunc() 
{ 
} 

enum{e1}e; 

// check by passing type as template argument 
template <typename T> 
void check() 
{ 
    if (IsClassT<T>::Yes) { 
        std::cout << " IsClassT " << std::endl; 
    } 
    else { 
        std::cout << " !IsClassT " << std::endl; 
    } 
} 
template <typename C> 
class ElementT { 
public: 
    typedef typename C::value_type Type; 
}; 
// check by passing type as function call argument 
template <typename T> 
void checkT (T) 
{ 
    check<T>(); 
} 


int main() 
{ 
    std::cout << "int: "; 
    check<int>(); 

    std::cout << "MyClass: "; 
    check<MyClass>(); 

    std::cout << "MyStruct:"; 
    MyStruct s; 
    checkT(s); 

    std::cout << "MyUnion: "; 
    check<MyUnion>(); 

    std::cout << "enum:    "; 
    checkT(e); 

    std::cout << "myfunc():"; 
    checkT(myfunc); 
} 

四.引用和限定符

incr 函数将会使apply模板函数演绎成T&& arg,需要注意这点

#include <iostream> 

template <typename T> 
void apply (T& arg, void (*func)(T)) 
{ 
    func(arg); 
} 

void incr (int& a) 
{ 
    ++a; 
} 

void print (int a) 
{ 
    std::cout << a << std::endl; 
} 

int main() 
{ 
    int x=7; 
    apply (x, print); 
    //error
    //apply (x, incr); 
} 

五.IfThenElse模板

用一个布尔值和特化技术来选择类型

template<bool C, typename Ta, typename Tb> 
class IfThenElse; 

// partial specialization: true yields second argument 
template<typename Ta, typename Tb> 
class IfThenElse<true, Ta, Tb> { 
public: 
    typedef Ta ResultT; 
}; 

// partial specialization: false yields third argument 
template<typename Ta, typename Tb> 
class IfThenElse<false, Ta, Tb> { 
public: 
    typedef Tb ResultT; 
};