STL学习笔记(0)可能困惑的C++语法
1. __STL_STATIC_TEMPLATE_MEMBER_BUG
如果编译器无法处理static member of template classes(模板类静态成员)就定义
。
即对于模板类中,模板类型不同时的静态变量不同。
template <typename T>
class test{
public:
static int _data;
}
int test<int>::_data=1;
int test<char>::_data=2;
2.__STL_CLASS_PARTIAL_SPECIALIZATION
如果编译器支持 partial specialization of class templates(模板类偏特化)就定义。
在模板类一般化设计之外(全特化),针对某些template做特殊设计。
“所谓的partial specialization的另一个意思是提供另一份template定义式,而其本身仍是templatized”
全特化就是所有的模板都为具体的类。
T* 特化允许用指针类型匹配的模式(也只能匹配指针类型)。
const T* 特化允许使用指向const的指针 类型匹配(也只能匹配指向const的指针)。
//一般化设计,非特化情况均使用这个
template <class I,class O>
struct test{
test() { cout << "I, O" <<endl; }
};
//特殊化设计1(偏特化1)
template <class T>
struct test <T* ,T*> {
test() { cout << "T* ,T*" << endl; }
};
//特殊化设计2(偏特化2)
template <class T>
struct test <const T* ,T*> {
test() { cout << "const T* ,T*" << endl; }
};
//测试
int main() {
test<int, char> obj1; //I, O
test<int*, int*> obj2; //T*, T*
test<const int*, int*> obj3; //const T*, T*
}
3 __STL_FUNCTION_TMPL_PARTIAL_ORDER
如果编译器支持partial ordering of function templates或者说partial specialization of function templates就定义。
template <class T,class Alloc=alloc>
class vec {
public:
void swap(vec<T, Alloc>&) { cout << "swap1()" << endl; }
};
#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
template <class T, class Alloc = alloc>
inline void swap(vec<T, Alloc>& a, vec<T, Alloc>& b) { a.swap(b); }
#endif
int main() {
vec<int> a, b;
swap(a, b);
}
4__STL_MEMBER_TEMPLATES
如果编译器支持template members of classes(模板类内嵌套模板) 就定义。
class vec {
public:
typedef T value_type;
typedef value_type* iterator;
template<class I>
void insert(iterator position, I first, I last) {
cout << "insert()" << endl;
}
};
int main() {
int ia[5] = { 0,1,2,3,4 };
vec<int> a;
vec<int>::iterator ite;
a.insert(ite, ia, ia + 5);
}
5. __STL_LIMITED_DEFAULT_TEMPLATES
如果编译器支持一个template参数可以根据前一个template的参数设置就定义。
template <class T,class Alloc=alloc,size_t BufSiz=0>
class deque {
public:
deque() { cout << deque() << endl; }
};
template <class T,class Sequence=deque<T>>
class stack {
public:
stack() { cout << "Stack" << endl; }
private:
Sequence c;
};
int main() {
stack<int> x;
}
6__STL_NON_TYPE_TMPL_PARAM_BUG
测试类模板是否使用非类型模板参数(non-type template parameters) 。
当以类型(type)作为模板参数的时候,代码中未决定的是类型;
当以一般的数字(non-type)作为模板参数的时候,代码中待定的内容便是某些数值。使用者这种模板必须要显示指定数值,模板才能实例化。
通常它们只能是常数整数(constant integral values )包括枚举,或者是指向外部链接的指针。
不能把float,class-type类型的对象,内部链接(internal linkage )对象,作为非类型模板参数。
template <class T,class Alloc=alloc,size_t BufSiz=0> //BufSiz即为非类型模板。
class deque {
public:
deque() { cout << deque() << endl; }
};
7 __STL_NULL_TMPL_ARGS
直接理解为若允许**bound friend template(约束模板友元)**则定义为 <> ,否则为空。
friend bool ooperator== __STL_NULL_TMPL_ARGS(const stack&,const stack&);
展开后变成
friend bool ooperator== <>(const stack&,const stack&);
**bound friend template(约束模板友元)**即有缘类型取决于类被初始化时的类型,但程序必须在类外为友元提供模板定义。
template <class T,class Sequence=deque<T>>
class stack {
//最标准的写法
friend bool operator== <T>(const stack<T>&, const stack<T>&);
friend bool operator< <T>(const stack<T>&, const stack<T>&);
//参数列表中的<T>实际上可以忽略
friend bool operator== <T>(const stack&, const stack&);
friend bool operator< <T>(const stack&, const stack&);
//当可以从参数中推断出模板类型时,可以改用<>
friend bool operator== <>(const stack&, const stack&);
friend bool operator< <>(const stack&, const stack&);
//下面用法是错误的!
//friend bool operator== (const stack&, const stack&);
//friend bool operator< (const stack&, const stack&);
public:
stack() { cout << "Stack" << endl; }
private:
Sequence c;
};
//定义部分懒得写了,但必须要写!
8.__STL_TEMPLATE_NULL
即 template <> 显示的模板特化 。
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
# define __STL_TEMPLATE_NULL template<>
#else
# define __STL_TEMPLATE_NULL
#endif
**模板特化(class template explicit specialization)**即指定一种或多种模板形参的实际值或实际类型,作为特殊情况。(与模板类型偏特化不同!)
template<class type> struct __type_traits{ ...};//非特化情况均使用这个
__STL_TEMPLATE_NULL struct __type_traits<char> { ... };//特化char情况
template<class Key> struct hash { };//非特化情况均使用这个
__STL_TEMPLATE_NULL struct hash<char> { ... };//特化char情况
__STL_TEMPLATE_NULL struct hash<unsgned char> { ... };//特化unsigned char情况
经展开后:
template<class type> struct __type_traits{ ...};//非特化情况均使用这个
template<> struct __type_traits<char> { ... };//特化char情况
template<class Key> struct hash { };//非特化情况均使用这个
template<> struct hash<char> { ... };//特化char情况
template<> struct hash<unsgned char> { ... };//特化unsigned char情况
9 function call操作符与仿函数
对某一类重载其()操作,并可指定初值,使用时相当于调用该类的临时对象的()操作。常用于与算法的搭配上。
template<typename T>
class print {
public:
void operator()(const T& elem) {
cout << elem << " ";
}
};
template<typename T>
class plus{
public:
T operator()(const T& x, const T& y)const { return x + y; }
};
int main() {
vector<int> ai({ 1,2,3,4,5 });
for_each(ai.begin(), ai.end(), print<int>());
int a = 5, b = 3;
print<int>()(plus<int>()(a, b));
}