traits技法的诞生原因,模版的类型推导只能作用于函数的参数,并不能作用于函数的返回值。
例如以下这种情况,可以内嵌typedef去定义返回类型。
template <typename T>
struct Iter {
typedef T value_type;
.....
T& operator*() {....}
}
template <typename Iter>
typename Iter::value_type
func(Iter iter) {
return *iter;
}
这样做的问题是,对于非class_type的迭代器无效,例如原生指针
stl的算法模版并不只能用于class type,对于原生的非容器类也能很好的支持,比如我可以对一个
原生数组使用stl的find方法。指针也是迭代器,支持迭代器的一切操作。(迭代器也是根据指针的思想去设计的)
如何支持原生指针呢?偏特化可以做到。
偏特化是对于一个模版类,指定其某一个或者几个模版参数从而诞生的新模版。
例如,我们有一个模版类
templage <typename A, typename B, typename C>
class Tc {
...
}
然后我们可以特化一个版本
template <typename A, typename B, typename C>
class Tc<A, B, C*> {
....//根据参数列表特化的一个版本,也就是说,任何第三个参数是原生指针的Tc类,都会由此模版而不是第一个模版去产生
}
再比如:
template <typename T>
class A {
bool isEqual(const T& a, const T& b) {
return a == b;
}
}
//对于没有实现==的类(最好去实现他,这里只是举个例子),或者不能直接用==比较的类
template <>
class A<T> {
bool isEqual(const T& a, const T& b) {
bool result = false;
....//your own way
return result;
}
}
traits 技术正是利用偏特化特性,萃取迭代器(目前看来只有容器和迭代器在用)的类型信息
比如:
template <typename I>
struct IterTraits {
typedef I value_type;
}
这样一来,上面的func可以这样写:
template <typename I>
IterTraits<I>::value_type
func(I iter) {
return *iter;
}
对于原生指针,可以偏特化一个traits,func函数不用做任何改动
template <typename I>
struct IterTraits<I*> {
typedef I value_type;
}
例如以下这种情况,可以内嵌typedef去定义返回类型。
template <typename T>
struct Iter {
typedef T value_type;
.....
T& operator*() {....}
}
template <typename Iter>
typename Iter::value_type
func(Iter iter) {
return *iter;
}
这样做的问题是,对于非class_type的迭代器无效,例如原生指针
stl的算法模版并不只能用于class type,对于原生的非容器类也能很好的支持,比如我可以对一个
原生数组使用stl的find方法。指针也是迭代器,支持迭代器的一切操作。(迭代器也是根据指针的思想去设计的)
如何支持原生指针呢?偏特化可以做到。
偏特化是对于一个模版类,指定其某一个或者几个模版参数从而诞生的新模版。
例如,我们有一个模版类
templage <typename A, typename B, typename C>
class Tc {
...
}
然后我们可以特化一个版本
template <typename A, typename B, typename C>
class Tc<A, B, C*> {
....//根据参数列表特化的一个版本,也就是说,任何第三个参数是原生指针的Tc类,都会由此模版而不是第一个模版去产生
}
再比如:
template <typename T>
class A {
bool isEqual(const T& a, const T& b) {
return a == b;
}
}
//对于没有实现==的类(最好去实现他,这里只是举个例子),或者不能直接用==比较的类
template <>
class A<T> {
bool isEqual(const T& a, const T& b) {
bool result = false;
....//your own way
return result;
}
}
traits 技术正是利用偏特化特性,萃取迭代器(目前看来只有容器和迭代器在用)的类型信息
比如:
template <typename I>
struct IterTraits {
typedef I value_type;
}
这样一来,上面的func可以这样写:
template <typename I>
IterTraits<I>::value_type
func(I iter) {
return *iter;
}
对于原生指针,可以偏特化一个traits,func函数不用做任何改动
template <typename I>
struct IterTraits<I*> {
typedef I value_type;
}