一.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);三.确定一个对象是否是类类型
#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; };