由来
在设计迭代器(iterator)时,考虑到需要经常访问迭代器所指对象之类型,称之为该迭代器的value_type
,利用内嵌类型声明typedef可轻松实现隐藏所指对象类型:
template<typename T>
struct Iterator
{
typedef T value_type;
}
如此一来,泛型算法便可通过typename Iterator<T>::value_type
获取value_type
:
template<typename Iterator>
typename Iterator::value_type getValue(Iterator iter)
{
return *iter;
}
在客户端,我们可做如下形式的调用:
vector<int> ivec{0, 1, 2, 3};
int val = getValue(ivec.begin());
STL要求,支持迭代器的算法,也应该支持原生指针,比如:
int arr[] = {0, 1, 2};
int val = getValue(arr+1);
# 此时编译器会报错
因为int*
类型(也即原生指针)不能内嵌类型声明,这里需要多一层的封装,萃取编译技术应运而生。进一步封装,便可进一步特化。
template<typename Iterator>
struct iterator_traits
{
typedef typename Iterator::value_type value_type;
};
// 特化版本一,针对原生指针类型
template<typename T>
struct iterator_triats<T*>
{
typedef T value_type;
};
// 特化版本二,
template<typename T>
struct iterator_traits<const T*>
{
typedef T value_type;
};
// 重写getValue()方法
template<typename Iterator>
typename iterator_traits<Iterator>::value_type getValue(Iterator iter)
{
return *iter;
}
这时便可实现对原生指针类型的支持:
int val = getValue(arr+1);
类型萃取(type traits)
struct __true_type{};
struct __false_type{};
template<typename T>
struct __type_traits
{
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_destructor;
};
template<>
struct __type_traits<int>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_destructor;
};