STL中关于类型提取器的详细介绍,我再此就不赘述了,只是记下其中关键部分,供我以后学习之用。
nested type,这种方法能获得一个类的associated type,如下代码中,想要获得myIter类的T类型,可以在此类中
nested一个typedef,将T保存下来,其他类中,就可以使用typename I::value_type来获得I类中nested进去的type(typename的作用就是告诉编译器I是一个类,不然无法通过编译)。
template
<
class
T
>
struct
myIter
{
typedef
T
value_type
;
T
* ptr;
myIter(
T
*
p
= 0):ptr(
p
){}
T
& operator*()
{
return
*ptr;
}
};
template
<
class
I
>
typename
I
::
value_type
func(
I
ite
)
{
func_aux(
ite
, *
ite
);
return
*
ite
;
}
当myIter如果是一个特别版本,比如一个原生指针(也可以看作一个迭代器),我们就无法拿到他的nested type,因为他是基本类型,根本就没有template,所以没有定义nested type。这样的话就要使用template partial specialization(偏特化)。
template
<
class
T
>
class
C
{};
//泛化版本接受T为任何类型
template
<
class
T
>
class
C
<
T
*> {};
//这个特化版本仅接受T是一个原生指针的情况
下面是iterator_traits的代码,只简单取了一部分
template
<
class
I
>
struct
iterator_traits
{
typedef
typename
I
::
value_type
vaule_type
;
//如果I有定义自己的value_type,就会被提取出来。
};
template
<
class
I
>
struct
iterator_traits
<T*>{
typedef
I vaule_type;
//特化版本,适用于原生指针
};
template
<
class
I
>
struct
iterator_traits
<
const
T*>{
typedef
T vaule_type;
//特化版本,适用于const指针,并且返回的是一个非const对象。
};
STL中的iterator一共有五个属性:
template
<
class
_Iterator
>
struct
iterator_traits
{
typedef
typename
_Iterator
::
iterator_category
iterator_category
;
typedef
typename
_Iterator
::
value_type
value_type
;
typedef
typename
_Iterator
::
difference_type
difference_type
;
typedef
typename
_Iterator
::
pointer
pointer
;
typedef
typename
_Iterator
::
reference
reference
;
};
其他几个都比较简单,只有iterator_categoty比较复杂,我们需要使用它来进行参数推导,以便提高效率,我们可以看到下面的声明,因为要进行编译时期的参数推导,我们需要为这些类型定义成类。而不能只是一个typedef。如下的继承关系,越往下iterator的功能越强大,比如random_access_iterator_tag就可以随机访问,拥有此能力的迭代器,我们必须使用他的高级功能以提高效率。
struct
input_iterator_tag
{};
struct
output_iterator_tag
{};
struct
forward_iterator_tag
:
public
input_iterator_tag
{};
struct
bidirectional_iterator_tag
:
public
forward_iterator_tag
{};
struct
random_access_iterator_tag
:
public
bidirectional_iterator_tag
{};
如果我要实现一个iterator,如下:
template
<
class
T
>
struct
myIter
{
typedef
bidirectional_iterator_tag
iterator_category
;
};
调用时只需:
template
<
class
InputIterator
,
class
Distance
>
inline
void
advance(
InputIterator
&
i
,
Distance
n
)
{
__advance(
i
,
n
,
iterator_traits
<
InputIterator
>::iterator_category());
//创建临时对象,此对象是无用的,只是为了进行参数推导。
}