备忘:
template造成的代码膨胀问题?
实际上,膨胀的是多数是目标代码,而非源代码,后者通常是变小了。template主要目的之一就是为了源代码复用,复用当然是避免代码冗余了。
几种膨胀的情形:
1。template中参数无关的代码会导致代码膨胀。
解决:分离之,如可以提到模版的基类。
typename与class 关键字的区别?
template的参数
参数可以是type和non-type,个数无限制,但不能有相同名称相同但参数个数不同的模版共存。
template<class T>
class MyTemplateClass {...} ;
template<int i>
class MyTemplateClass {...};
template的特化
template必须特化才能使用。特化分全特化和局部特化。
其中,局部可以是参数的个数,也可以是参数的类型范围,如type和pointer type
编译器会匹配最符合的版本。
template<typename T>
特化版本:(指针类型)
template<typename T>
class MyTemplateClass<T*> {};
所有指针类型都会使用这一实现,如: MyTemplateClass<int* > c;
Functor
与callback function的比较:
1.Functor的灵活性更好,无需signature
2.Functor能携带更多的信息,因为它是一个object
template function的返回值类型
只能跟参数类型一致,如果有的话。
Adapter
Container Adapters
例子:stack,queue: 配接/使用deque
Function/Functor Adapters
例子:negater,binder,composer
就是一个Functor包装其内部adaptable functor的接口变成想要的接口
Iterator Adapters
例子:istream_iterator,ostream_iterator,reverser,inserter
Proxy
为对象提供一个代理,用以控制对该对象的存取。
例子:std::vector<bool>, std::string (support ref couting)
details:
std::string (support ref couting)
[] 操作符不能区分是lvalue or rvalue,就不好判断该操作是否会改变对象值。此时,如使用proxy,可以判断对象的读写操作。
一般rvalue肯定用到了proxy的转型函数,如:cout<<s[1];
lvalue对应proxy的assignment操作符或者copy constructor,或者operator &
如:s[2] = 'x'; / s[3] = s[4]; / char* p = &(s[5]);
支持ref couting的std::string与smartpointer对象的区别:
后者一般会传递所指对象的所有权,而前者不会。
五种iterator的类型以及关系
input_iterator_tag/output_iterator_tag
/|\
|
forward_iterator_tag
/|\
|
bidirectional_iterator_tag
/|\
|
random_access_iterator_tag
其中,random_access_iterator_tag灵活性最高,类似native pointer行为。
forward_iterator_tag是继承自input_iterator_tag,它派生了什么行为?
Traits
type traits
type特性指的是这个type是否具有non-trival default ctor/copy ctor/assignment op/dtor?如果是否定的,那么在对这些type进行构造拷贝赋值析构时就可以采取优化措施。
iterator traits
能够由iterator得到其所指的对象类型以及相应类型(associated types): value type/difference type/reference type/pointer type/iterator tags