c++ template(10)类型函数
2013-04-25 14:14 Clingingboy 阅读(1293) 评论(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;
};