STL源码-iterator traits编程技法(续)
2014-12-28 22:28
218 查看
http://blog.csdn.net/xietingcandice/article/details/39958733
[cpp] view
plaincopyprint?
<span style="background-color: rgb(255, 255, 255);">// Filename: type_traits.h
// Comment By: 凝霜
// E-mail: mdl2009@vip.qq.com
// Blog: http://blog.csdn.net/mdl13412
/*
*
* Copyright (c) 1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
#ifndef __TYPE_TRAITS_H
#define __TYPE_TRAITS_H
#ifndef __STL_CONFIG_H
#include <stl_config.h>
#endif
// 这个头文件提供了一个框架, 允许编译器在编译期根据类型属性派发函数的机制
// 这个框架对于编写模板代码非常有用
// 例如, 当我们需要拷贝一个未知类型的array, 它能帮助我们得知这个未知类型
// 是否具有一个trivial copy constructor, 以帮助我们决定memcpy()是否能使用
// __type_traits模板类提供了一些列的typedefs, 其值是__true_type或者__false_type
// __type_traits模板类可以接受任何类型的参数
// 模板类中的typedefs可以通过以下手段获取其正确值
// 1. general instantiation, 对于所有类型都要有保守值
// 2. 经过特化的版本
// 3. 一些编译器(例如Silicon Graphics N32 and N64 compilers)
// 会自动给所有类型提供合适的特化版本
//
// 例子:
// Copy an array of elements which have non-trivial copy constructors
// template <class T> void copy(T* source,T* destination,int n,__false_type);
// Copy an array of elements which have trivial copy constructors. Use memcpy.
// template <class T> void copy(T* source,T* destination,int n,__true_type);
//
// Copy an array of any type by using the most efficient copy mechanism
// template <class T> inline void copy(T* source,T* destination,int n)
// {
// copy(source,destination,n,
// typename __type_traits<T>::has_trivial_copy_constructor());
// }
struct __true_type
{
};
struct __false_type
{
};
template <class type>
struct __type_traits
{
// 不要移除这个成员
// 它通知能自动特化__type_traits的编译器, 现在这个__type_traits template是特化的
// 这是为了确保万一编译器使用了__type_traits而与此处无任何关联的模板时
// 一切也能顺利运作
typedef __true_type this_dummy_member_must_be_first;
// 以下条款应当被遵守, 因为编译器有可能自动生成类型的特化版本
// - 你可以重新安排的成员次序
// - 你可以移除你想移除的成员
// - 一定不可以修改下列成员名称, 却没有修改编译器中的相应名称
// - 新加入的成员被当作一般成员, 除非编译器提供特殊支持
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
// 以下针对C++内置的基本数据类型提供特化版本, 使其具有trivial default constructor,
// copy constructor, assignment operator, destructor
// 并标记其为POD类型
//
// 特化类型:
// char, signed char, unsigned char,
// short, unsigned short
// int, unsigned int
// long, unsigned long
// float, double, long double
// Provide some specializations. This is harmless for compilers that
// have built-in __types_traits support, and essential for compilers
// that don't.
__STL_TEMPLATE_NULL struct __type_traits<char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<signed char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<short>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned short>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<int>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned int>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<long>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned long>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<float>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<double>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<long double>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
// 针对指针提供特化
template <class T>
struct __type_traits<T*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
// 针对char *, signed char *, unsigned char *提供特化
struct __type_traits<char*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<signed char*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<unsigned char*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
#endif /* __TYPE_TRAITS_H */
// Local Variables:
// mode:C++
// End:
</span>
上面大概讲的是types_trait其实对这方面我现在还不是理解得很好,在之后的理解中再回来补充吧
下面是我看见的一个理解trait比较好的例子
下面有一个模板函数,假设一个动物收容组织提供了它,他们接受所有无家可归的可怜的小动物,于是他们向外界提供了一个函数接受注册。函数看起来像这样:
[cpp] view
plaincopyprint?
template<class T> //T表示接受的是何种动物
void AcceptAnimals(T animal)
{
... //do something
};
但是,如果他们想将猫和狗分开处理(毕竟饲养一只猫和饲养一只狗并不相同。他们可能会为狗买一根链子,而温顺的猫则可能不需要)。一个可行的方法是分别提供两个函数:AcceptDog和AcceptCat,然而这种解决办法并不优雅(想想看,注册者可能既有一只猫又有一只狗,这样他不得不调用不同的函数来注册,而且,如果种类还在增多呢,那样会导致向外提供的接口的增多,注册者因此而不得不记住那些烦琐的名字,而这显然没有只需记住AccpetAnimal这一个名字简单)。如果想保持这个模板函数,并将它作为向外界提供的唯一接口,则我们需要某种方式来获取型别T的特征(trait),并按照不同的特征来采用不同的策略。这里我们有第二个解决办法:
约定所有的动物类(如class Cat,class Dog)都必须在内部typedef一个表明自己身份的型别,作为标识的型别如下:
[cpp] view
plaincopyprint?
struct cat_tag{}; //这只是个空类,目的是激发函数重载,后面会解释
struct dog_tag{}; //同上
于是,所有狗类都必须像这样:
[cpp] view
plaincopyprint?
class Dog
{
public:
typedef dog_tag type; //型别(身份)标志,表示这是狗类,如果是猫类则为typedef cat_tag type;
...
}
然后,动物收容组织可以在内部提供对猫狗分开处理的函数,像这样:
[cpp] view
plaincopyprint?
template<class T>
void Accept(T dog,dog_tag) //第二个参数为无名参数,只是为了激发函数重载
{...}
template<class T>
void Accpet(T cat,cat_tag) //同上
{...}
//于是先前的Accept函数可以改写如下:
template<class T>
void Accept(T animal) //这是向外界提供的唯一接口
{
1 Accept(animal,typename T::type()); //如果T为狗类,则typename T::type就是dog_tag,那么
//typename T::type()就是创建了一个dog_tag类的临时对象,
//根据函数重载的规则,这将调用Accept(T,dog_tag)的版本,
//这正是转向处理狗的策略
//如果T为猫类,则typename T::type为cat_tag,由上面的推导,
//这将调用Accept(T,cat_tag)的版本,转向处理猫的策略
} //typename 关键字告诉编译器T::type是个型别而不是静态成员
所有型别推导,函数重载,都在编译期完成,你几乎不用耗费任何运行期成本(除了创建dog_tag,cat_tag临时对象的成本,然而经过编译器的优化,这种成本可能也会消失)就拥有了可读性和可维护性高的代码。“但是,等等!”你说:“traits在哪?”,typename T::type其实就是traits,只不过少了一层封装而已,如果像这样作一些改进:
[cpp] view
plaincopyprint?
template<typename T>
struct AnimalTraits
{
typedef T::type type;
};
于是1处的代码可以写成Accept(animal,typename AnimalTraits<T>::type());
效率
通常为了提高效率,为某种情况采取特殊的措施是必要的,例如STL里面的copy,原型像这样:
template<typename IterIn,typename IterOut>
IterOut copy(IterIn first,IterIn last,IterOut dest){//将[first,last)区间内的元素拷贝到以dest开始的地方
return copy_opt(first,last,dest,ptr_category(first,dest)); //ptr_category用来萃取出迭代器的类别以进行
//适当程度的优化
}
copy_opt有两个版本,其中一个是针对如基本型别的数组作优化的,如果拷贝发生在char数组间,那么根本用不着挨个元素赋值,基于数组在内存中分布的连续性,可以用速度极快的memmove函数来完成。ptr_category有很多重载版本,对可以使用memmove的情况返回一个空类如scalar_ptr的对象以激发函数重载。其原始版本则返回空类non_scalar_ptr的对象。copy_opt的两个版本于是像这样:
template<typename IterIn,typename IterOut>
IterOut copy(IterIn first,IterIn last,IterOut dest,scalar_ptr){ ...} //使用 memmove
template<typename IterIn,typename IterOut>
IterOut copy(IterIn first,IterIn last,IterOut dest,non_scalar_ptr){ ...} //按部就班的逐个拷贝
其实通常为了提高效率,还是需要分派。
[cpp] view
plaincopyprint?
<span style="background-color: rgb(255, 255, 255);">// Filename: type_traits.h
// Comment By: 凝霜
// E-mail: mdl2009@vip.qq.com
// Blog: http://blog.csdn.net/mdl13412
/*
*
* Copyright (c) 1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
#ifndef __TYPE_TRAITS_H
#define __TYPE_TRAITS_H
#ifndef __STL_CONFIG_H
#include <stl_config.h>
#endif
// 这个头文件提供了一个框架, 允许编译器在编译期根据类型属性派发函数的机制
// 这个框架对于编写模板代码非常有用
// 例如, 当我们需要拷贝一个未知类型的array, 它能帮助我们得知这个未知类型
// 是否具有一个trivial copy constructor, 以帮助我们决定memcpy()是否能使用
// __type_traits模板类提供了一些列的typedefs, 其值是__true_type或者__false_type
// __type_traits模板类可以接受任何类型的参数
// 模板类中的typedefs可以通过以下手段获取其正确值
// 1. general instantiation, 对于所有类型都要有保守值
// 2. 经过特化的版本
// 3. 一些编译器(例如Silicon Graphics N32 and N64 compilers)
// 会自动给所有类型提供合适的特化版本
//
// 例子:
// Copy an array of elements which have non-trivial copy constructors
// template <class T> void copy(T* source,T* destination,int n,__false_type);
// Copy an array of elements which have trivial copy constructors. Use memcpy.
// template <class T> void copy(T* source,T* destination,int n,__true_type);
//
// Copy an array of any type by using the most efficient copy mechanism
// template <class T> inline void copy(T* source,T* destination,int n)
// {
// copy(source,destination,n,
// typename __type_traits<T>::has_trivial_copy_constructor());
// }
struct __true_type
{
};
struct __false_type
{
};
template <class type>
struct __type_traits
{
// 不要移除这个成员
// 它通知能自动特化__type_traits的编译器, 现在这个__type_traits template是特化的
// 这是为了确保万一编译器使用了__type_traits而与此处无任何关联的模板时
// 一切也能顺利运作
typedef __true_type this_dummy_member_must_be_first;
// 以下条款应当被遵守, 因为编译器有可能自动生成类型的特化版本
// - 你可以重新安排的成员次序
// - 你可以移除你想移除的成员
// - 一定不可以修改下列成员名称, 却没有修改编译器中的相应名称
// - 新加入的成员被当作一般成员, 除非编译器提供特殊支持
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
// 以下针对C++内置的基本数据类型提供特化版本, 使其具有trivial default constructor,
// copy constructor, assignment operator, destructor
// 并标记其为POD类型
//
// 特化类型:
// char, signed char, unsigned char,
// short, unsigned short
// int, unsigned int
// long, unsigned long
// float, double, long double
// Provide some specializations. This is harmless for compilers that
// have built-in __types_traits support, and essential for compilers
// that don't.
__STL_TEMPLATE_NULL struct __type_traits<char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<signed char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<short>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned short>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<int>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned int>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<long>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned long>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<float>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<double>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<long double>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
// 针对指针提供特化
template <class T>
struct __type_traits<T*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
// 针对char *, signed char *, unsigned char *提供特化
struct __type_traits<char*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<signed char*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<unsigned char*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
#endif /* __TYPE_TRAITS_H */
// Local Variables:
// mode:C++
// End:
</span>
上面大概讲的是types_trait其实对这方面我现在还不是理解得很好,在之后的理解中再回来补充吧
下面是我看见的一个理解trait比较好的例子
下面有一个模板函数,假设一个动物收容组织提供了它,他们接受所有无家可归的可怜的小动物,于是他们向外界提供了一个函数接受注册。函数看起来像这样:
[cpp] view
plaincopyprint?
template<class T> //T表示接受的是何种动物
void AcceptAnimals(T animal)
{
... //do something
};
但是,如果他们想将猫和狗分开处理(毕竟饲养一只猫和饲养一只狗并不相同。他们可能会为狗买一根链子,而温顺的猫则可能不需要)。一个可行的方法是分别提供两个函数:AcceptDog和AcceptCat,然而这种解决办法并不优雅(想想看,注册者可能既有一只猫又有一只狗,这样他不得不调用不同的函数来注册,而且,如果种类还在增多呢,那样会导致向外提供的接口的增多,注册者因此而不得不记住那些烦琐的名字,而这显然没有只需记住AccpetAnimal这一个名字简单)。如果想保持这个模板函数,并将它作为向外界提供的唯一接口,则我们需要某种方式来获取型别T的特征(trait),并按照不同的特征来采用不同的策略。这里我们有第二个解决办法:
约定所有的动物类(如class Cat,class Dog)都必须在内部typedef一个表明自己身份的型别,作为标识的型别如下:
[cpp] view
plaincopyprint?
struct cat_tag{}; //这只是个空类,目的是激发函数重载,后面会解释
struct dog_tag{}; //同上
于是,所有狗类都必须像这样:
[cpp] view
plaincopyprint?
class Dog
{
public:
typedef dog_tag type; //型别(身份)标志,表示这是狗类,如果是猫类则为typedef cat_tag type;
...
}
然后,动物收容组织可以在内部提供对猫狗分开处理的函数,像这样:
[cpp] view
plaincopyprint?
template<class T>
void Accept(T dog,dog_tag) //第二个参数为无名参数,只是为了激发函数重载
{...}
template<class T>
void Accpet(T cat,cat_tag) //同上
{...}
//于是先前的Accept函数可以改写如下:
template<class T>
void Accept(T animal) //这是向外界提供的唯一接口
{
1 Accept(animal,typename T::type()); //如果T为狗类,则typename T::type就是dog_tag,那么
//typename T::type()就是创建了一个dog_tag类的临时对象,
//根据函数重载的规则,这将调用Accept(T,dog_tag)的版本,
//这正是转向处理狗的策略
//如果T为猫类,则typename T::type为cat_tag,由上面的推导,
//这将调用Accept(T,cat_tag)的版本,转向处理猫的策略
} //typename 关键字告诉编译器T::type是个型别而不是静态成员
所有型别推导,函数重载,都在编译期完成,你几乎不用耗费任何运行期成本(除了创建dog_tag,cat_tag临时对象的成本,然而经过编译器的优化,这种成本可能也会消失)就拥有了可读性和可维护性高的代码。“但是,等等!”你说:“traits在哪?”,typename T::type其实就是traits,只不过少了一层封装而已,如果像这样作一些改进:
[cpp] view
plaincopyprint?
template<typename T>
struct AnimalTraits
{
typedef T::type type;
};
于是1处的代码可以写成Accept(animal,typename AnimalTraits<T>::type());
效率
通常为了提高效率,为某种情况采取特殊的措施是必要的,例如STL里面的copy,原型像这样:
template<typename IterIn,typename IterOut>
IterOut copy(IterIn first,IterIn last,IterOut dest){//将[first,last)区间内的元素拷贝到以dest开始的地方
return copy_opt(first,last,dest,ptr_category(first,dest)); //ptr_category用来萃取出迭代器的类别以进行
//适当程度的优化
}
copy_opt有两个版本,其中一个是针对如基本型别的数组作优化的,如果拷贝发生在char数组间,那么根本用不着挨个元素赋值,基于数组在内存中分布的连续性,可以用速度极快的memmove函数来完成。ptr_category有很多重载版本,对可以使用memmove的情况返回一个空类如scalar_ptr的对象以激发函数重载。其原始版本则返回空类non_scalar_ptr的对象。copy_opt的两个版本于是像这样:
template<typename IterIn,typename IterOut>
IterOut copy(IterIn first,IterIn last,IterOut dest,scalar_ptr){ ...} //使用 memmove
template<typename IterIn,typename IterOut>
IterOut copy(IterIn first,IterIn last,IterOut dest,non_scalar_ptr){ ...} //按部就班的逐个拷贝
其实通常为了提高效率,还是需要分派。
相关文章推荐
- STL源码-iterator traits编程技法
- STL源码-iterator traits编程技法(续)
- STL源码分析读书笔记--第三章--迭代器(iterator)概念与traits编程技法
- STL源码-iterator traits编程技法
- STL iterator和traits编程技法
- STL源码学习——迭代器(iterators)与traits编程技法
- 三 迭代器(iterator)概念与traits编程技法
- STL之traits编程技法
- 迭代器(Iterator)概念与traits编程技法
- STL中,traits编程技法+模板
- STL之traits编程技法
- STL笔记(7)——Traits编程技法(二)
- 【深度探索STL】详解 traits 编程技法
- STL中的Traits编程技法
- STL itertor概念和traits编程技法(一)
- STL之traits编程技法
- STL笔记(6)——Traits编程技法(一)
- STL中迭代器概念与traits编程技法
- 迭代器(iterator) 与 traits 编程技法
- 《STL 源码剖析读书笔记(一)》—–迭代器概念与trais编程技法