【c++ templates读书笔记】【4】技巧性基础知识
来源:互联网 发布:redial 软件 编辑:程序博客网 时间:2024/06/15 05:34
1、关键字typename
引入关键字typename是为了说明:模板内部的标识符可以是一个类型。当某个依赖与模板参数的名称是一个类型时,就应该使用typename。
template<T>class MyClass{typename T::SubType * ptr; // typename说明SubType是定义于T内的一种类型,如果不使用typename,SubType会被认为是T的一个静态成员...};
2、使用this->
对于那些在基类中声明,并且依赖于模板参数的符号(函数或变量等),应该在它们前面使用this->或者Base<T>::。
#include<iostream>using namespace std;template<typename T>class Base{public:void exit(){ cout << "exit" << endl; }};template<typename T>class Derived:Base<T>{public:void exitDerived(){this->exit();//但VS 2013中直接用exit()也能正确运行}};int main(){Derived<int> d;d.exitDerived();system("pause");return 0;}
3、成员模板
嵌套类和成员函数都可以作为模板,例子:#include<iostream>#include<deque>using namespace std;template<typename T>class Stack{private:deque<T> deq;public:void push(T const& elem);void pop();T top() const;bool empty() const{return deq.empty();}template<typename T2>//成员模板Stack<T>& operator=(Stack<T2> const& op2);};template<typename T>void Stack<T>::push(T const& elem){deq.push_back(elem);}template<typename T>void Stack<T>::pop(){if (deq.empty()){throw out_of_range("Stack<>::pop():empty stack");}deq.pop_back();}template<typename T>T Stack<T>::top() const{if (deq.empty()){throw out_of_range("Stack<>::pop():empty stack");}return deq.back();}template<typename T>template<typename T2>Stack<T>& Stack<T>::operator=(Stack<T2> const& op2){if ((void*)this == (void*)&op2)return *this;Stack<T2> tmp(op2);deq.clear();while (!tmp.empty()){deq.push_front(tmp.top());tmp.pop();}return *this;}int main(){try{Stack<float> istk;istk.push(7.2);istk.push(8.3);istk.push(9.4);cout << istk.top() << endl;istk.pop();cout << istk.top() << endl;Stack<int> sstk;sstk = istk;cout << sstk.top() << endl;sstk.pop();cout << sstk.top() << endl;}catch (exception const& ex){cerr << "Exception:" << ex.what() << endl;return EXIT_FAILURE;}system("pause");return 0;}
4、模板的模板参数
模板参数本身是模板,则该参数是模板的模板参数。函数模板不支持模板的模板参数。
例子:
#include<iostream>#include<deque>#include<vector>using namespace std;//这里Container是模板的模板参数template<typename T,template<typename ELEM,typename=allocator<ELEM>> class Container=deque>class Stack{private:Container<T> container;public:void push(T const& elem);void pop();T top() const;bool empty() const{return container.empty();}template<typename T2, template<typename ELEM2, typename = allocator<ELEM2>> class Container2>Stack<T, Container>& operator=(Stack<T2, Container2> const& op2);};template<typename T, template<typename ELEM, typename = allocator<ELEM>> class Container>void Stack<T,Container>::push(T const& elem){container.push_back(elem);}template<typename T, template<typename ELEM, typename = allocator<ELEM>> class Container>void Stack<T, Container>::pop(){if (container.empty()){throw out_of_range("Stack<>::pop():empty stack");}container.pop_back();}template<typename T, template<typename ELEM, typename = allocator<ELEM>> class Container>T Stack<T, Container>::top() const{if (container.empty()){throw out_of_range("Stack<>::pop():empty stack");}return container.back();}template<typename T, template<typename ELEM, typename = allocator<ELEM>> class Container>template<typename T2, template<typename ELEM2, typename = allocator<ELEM2>> class Container2>Stack<T, Container>& Stack<T, Container>::operator=(Stack<T2, Container2> const& op2){if ((void*)this == (void*)&op2)return *this;Stack<T2, Container2> tmp(op2);container.clear();while (!tmp.empty()){container.push_front(tmp.top());tmp.pop();}return *this;}int main(){try{Stack<double> dstk;dstk.push(7.2);dstk.push(8.3);dstk.push(9.4);cout << dstk.top() << endl;dstk.pop();cout << dstk.top() << endl;Stack<int> istk;istk = dstk;cout << istk.top() << endl;istk.pop();cout << istk.top() << endl;}catch (exception const& ex){cerr << "Exception:" << ex.what() << endl;return EXIT_FAILURE;}system("pause");return 0;}
5、使用字符串作为函数模板的实参
#include<iostream>#include<string>using namespace std;template<typename T>T const& Max(T const& a, T const& b){return a < b ? b : a;}int main(){string s = "abc";cout << Max("apple", "peach") << endl;//cout << Max("apple", "tomato") << endl;//错误,不同类型的实参//cout << Max("apple", s) << endl;//错误,不同类型的实参system("pause");return 0;}
上述例子在VS2013中运行错误。
上述例子中后面两个调用错误的问题在于:由于长度的区别,这些字符串属于不同的数组类型,”apple”和”peach”具有相同的类型char const[6],”tomato”的类型是char const[7],因此只有第一个调用合法。但声明的是非引用参数,可以使用不同的字符串作为参数。
#include<iostream>#include<string>using namespace std;template <typename T>T Max(T a, T b){return a < b ? b : a;}int main(){string s = "abc";cout << Max("apple", "peach") << endl;cout << Max("apple", "tomato") << endl;//正确,退化为相同的类型//cout << Max("apple", s) << endl;//错误,不同类型的实参system("pause");return 0;}
上述第二个调用正确,原因是对于非引用类型的参数,在实参演绎的过程中,会出现数组到指针的类型转换。但是这里比较的是指针,而不是两个字符串的字典序。
0 0
- 【c++ templates读书笔记】【4】技巧性基础知识
- C++ Templates:技巧性基础知识
- C++ Templates笔记 8 技巧性基础知识关键字typename
- 模板技巧性基础知识
- 模板笔记004 - 技巧性基础知识
- c/c++基础知识读书笔记一
- 《C++ Templates》读书笔记
- 转:《C++ Templates》读书笔记
- c/c++基础知识读书笔记二 格式化输入输出
- c/c++基础知识读书笔记四 初级指针
- C++读书笔记1:C语言基础知识
- 《Effective C++》读书笔记之item44:将与参数无关的代码抽离templates
- C++templates简单基础--Function Templates
- C++ Template之技巧性基础知识 和 typeid(x).name()用法
- 【读书笔记】iOS-Objective-C对C的扩展基础知识
- 复习C++基础知识-----“我的第一本C++”读书笔记4(终篇)
- 《C++ Templates》读书笔记的一点补充
- C++ Templates读书笔记1__函数模板
- Cannot SET AUTOTRACE 处理办法
- 第一个PHP程序——Hello World
- iOS提交应用至APP Store流程
- D3D动画相关接口理解
- SSH整合(二)——利用Spring来装配Action类
- 【c++ templates读书笔记】【4】技巧性基础知识
- 移动构造-C++11
- JavaScript高级程序设计之面向对象的程序设计之创建对象之 构造函数模式第6.2.2讲笔记
- 软件测试基础知识点整理
- Top 30 Nmap Command Examples For Sys/Network Admins
- 天声人語 20150927
- 剑指offer-顺时针打印矩阵
- JavaScript高级程序设计之面向对象的程序设计之创建对象之原型模式 第6.2.3讲笔记
- iOS开发:音乐播放器