标签:不能 const 泛化 temp lin 告诉 限制 tmp 模板类
主要讨论如何获取迭代器相应型别。使用迭代器时,很可能用到其型别,若需要声明某个迭代器所指对象的型别的变量,该如何解决。方法如下:
例如:
template<typename I, typename T>
void func_impl(I iter, T t)
{
//T为迭代器所指对象的型别
T tmp;
//.....
}
template<typename I>
inline
void func(I iter)
{
//func工作交给func_impl完成
func_impl(iter, *iter);
}
int main()
{
int i;
func(&i);
return 0;
}
func_impl()是一个 function template,一旦被调用,编译器会自动进行template参数推导,从而导出型别T,无需自己指出型别,解决问题。迭代器相应型别不只是迭代器所指对象的型别一种而已,最常用的相应型别有五种,但并非任何情况都可利用上述template参数推导机制来取得。这就需要其他方法。
迭代器所指对象的型别,成为该迭代器的value type,上述模板参数推导并非全面可用,在需要value type作为函数返回值时,就不能解决了。template参数推导的只是参数而已。因此,声明内嵌型别就出现了。
例如:
template<typename T>
struct MyIter
{
typedef T value_type; //内嵌型别声明
T* ptr;
MyIter(T* p = nullptr):ptr(p) { }
T& operator*() const { return *ptr;}
//...
};
template<typename I>
typename I::value_type //函数func()的返回类型,为I类型迭代器中的value_type
func(I ite)
{
return *ite;
}
int main()
{
MyIter<int> ite(new int(8));
cout<<func(ite); //输出8
return 0;
}
func()函数的返回值必须加上关键字typename,用来告诉编译器这时一个模板类型。但并不是所有迭代器都为class type,原生指针就不是,它就不能定义内嵌型别。这时模板偏特化(template partial specialization)就能解决这个问题。
如果class template拥有一个以上的template参数,我们可以针对其中某个(或数个,但并非全部)template参数进行特化工作。也就是将泛化版本中的某些template参数给予明确的指定。
如:
template<typename U, typename V, typename T>
class C { }
偏特化不是template参数U、V或T指定某个参数值,而是针对(任何)template参数更进一步的条件限制所设计出来的一个特化版本。看这个例子:
//泛化版本
template<typename T>
class C { }
//偏特化版本
template<typename T>
class C<T*> { } //解决原生指针的问题
如此便能解决前面的内嵌型别的问题。下面这个class template专门用来萃取迭代器的特性之一 :value_type
template<typename I>
struct Iterator_traits //traits指的是特性
{
typedef typename I::value_type value_type;
}
标签:不能 const 泛化 temp lin 告诉 限制 tmp 模板类
原文地址:https://www.cnblogs.com/vlyf/p/11854018.html