typename 的用法:
第一种template<typename T> 这种大家都知道, 和 template<class T> 一样,就不多讲解了
第二种: 嵌套从属名称
注意代码中的erase() 和 print() 以及 typedef list<T*> data_type
template<class T>class List{private:typedef list<T*> data_type;data_type _list;public://List(){}//explicit List(std::initializer_list<T*>object) { _list = object; }//void push(T *obj) { _list.push_back(obj); }void erase(){typename data_type::iterator T_begin = _list.begin();while(T_begin != _list.end()){if(*T_begin)delete *T_begin;T_begin++;}}//const data_type &data() {return _list;}void print(){typename data_type::iterator T_begin = _list.begin();while(T_begin != _list.end()){std::cout<<**T_begin<<std::endl;T_begin++;}}};
print() 函数中 T_begin 的类型是 data_type::iterator 实际上他的类型取决于typedef list<T*> data_type 也就是模板参数T. template 内出现的名称如果相依 某个 template 的参数称之为 从属名称. 如果从属名称在class 中呈 嵌套状, 就称为 嵌套从属名称
嵌套从属名称可能导致解析困难
在Effective c++ 书中 条款42: P203 有讲解
void print(){data_type::iterator *T_begin;}这其实是想表示一个指针, 因为代码是你写的,你自然知道, 别人可能会以为是相乘的动作.要改正这个错误,我门必须告知c++ data_type::iterator 是一个类型, 那末只要在他的前面 放置 typename 就可以了
关于模板函数的定义和声明:
最好是放在.h , 放在一起
参考文档: /coder-zyc/p/10030551.html
参考文档: /u010273652/article/details/21568131
参考文档: /questionTerminal/7ffeb7a8e2ef43dcaf6ee4cb69f17bf3?page=1&onlyReference=false