首页 > 代码库 > 【足迹C++primer】57、定义一个模板
【足迹C++primer】57、定义一个模板
定义一个模板
比较大小的函数如果v1和v2相同返回0,v1小-1,v2小1
int compare(const string &v1, const string &v2) { if(v1<v2) return -1; if(v1>v2) return 1; return 0; } int compare(const double &v1, const double &v2) { if(v1<v2) return -1; if(v1>v2) return 1; return 0; }
使用模板
template<typename T> int compare(const T &v1, const T &v2) { if(v1<v2) return -1; if(v2<v1) return 1; return 0; } //范例fun1 void fun1() { cout<<compare(1,0)<<endl; //T->int vector<int> vec1{1,2,3}, vec2{4,5,6}; //一个接一个地比,如果第一个相同那么比第二个,否则看第一个 cout<<compare(vec1, vec2)<<endl; //T->vector<int> }
模板类型参数
template<typename T> T foo(T* p) //返回类型是T { T temp=*p; //... return temp; }
非类型模板参数
有关键字typename和class来代表template<A,B>修饰A,B类型,但是也可以不用typename和class
template<unsigned N, unsigned M> int compare(const char (&p1)[N], const char (&p2)[M]) { return strcmp(p1, p2); //比较两个字符串。设这两个字符串为str1,str2,若str1=str2,则返回零;若str1>str2,则返回正数;若str1<str2,则返回负数。 } //inline和constexpr函数模板 template<typename T> inline T min(const T &, const T &); //这里inline不能放到template前面 template<typename T> int compare2(const T &v1, const T &v2) { if(less<T>()(v1, v2)) return -1; if(less<T>()(v1, v2)) return 1; return 0; }
类模板
定义类模板
template<typename T> class Blob { public: typedef T value_type; //using value_type=T; typedef typename vector<T>::size_type size_type; // using size_type=typename vector<T>::size_type; //构造函数 Blob(); Blob(initializer_list<T> il); //参数连串初始化 //元素个数 size_type size() const {return data->size();} //得到vector元素个数 bool empty() const {return data->empty();} //判断vector是否为空 //加减元素,拷贝 void push_back(const T &t) {data->push_back(t);} //移动版本,move,&&是右值引用!! void push_back(T &&t) { data->push_back(std::move(t));} void pop_back(); //删除一个元素 //元素调用 T &back(); //返回最后一个元素 T &operator[](size_type i); //下标运算符 private: shared_ptr<vector<T>> data; void check(size_type i, const string &msg) const; }; //实现定义 template<typename T> void Blob<T>::check(size_type i, const string &msg) const { if(i >= data->size()) //如果vector的大小 不大于i的话抛出异常 throw out_of_range(msg); } template<typename T> T &Blob<T>::back() { check(0, "back on empty Blob"); return data->back(); //返回最后一个元素 } template<typename T> //下标运算 T & Blob<T>::operator[](size_type i) { check(i, "subscript out of range"); //给出的下标是否超出范围 return (*data)[i]; } template<typename T> void Blob<T>::pop_back() { check(0, "pop_back on the empty Blob"); data->pop_back(); //删除元素一个 } //构造函数定义 template<typename T> Blob<T>::Blob():data(make_shared<vector<T>>()) {} template<typename T> Blob<T>::Blob(initializer_list<T> il):data(make_shared<vector<T>>(il)){} void fun2() { //类模板实例 Blob<int> ia; // Blob(); Blob<int> ia2={0,1,2,3,4};//Blob(initializer_list<T> il)参数连串初始化 Blob<int> squares={0,1,2,3,4,5,6,7,8,9}; for(size_t i=0 ; i != squares.size() ; ++i) { squares[i]=i*i; cout<<"数值是:"<<squares[i]<<"\t"; } }
用模板简化代码
template<typename T> class BlobPtr //使用时BlobPtr<T> a,b,c; { public: BlobPtr():curr(0) {} BlobPtr(Blob<T> &a, size_t sz=0):wptr(a.data), curr(sz) {} //初始化 T &operator*() const //一个()表示前缀 { auto p=check(curr, "dereference past end"); return (*p)[curr]; //这是*p指向vector } //前缀++,-- BlobPtr &operator++(); BlobPtr &operator--(); //后置++,-- BlobPtr &operator++(int); BlobPtr &operator--(int); private: shared_ptr<vector<T>> check(size_t, const string &) const; weak_ptr<vector<T>> wptr; size_t curr; }; //后缀++ -- template<typename T> BlobPtr<T> &BlobPtr<T>::operator++(int) { BlobPtr ret=*this; ++*this; return ret; } //后缀++ -- template<typename T> BlobPtr<T> &BlobPtr<T>::operator--(int) { BlobPtr ret=*this; --*this; return ret; }
模板和友元
template<typename> class BlobPtr; template<typename> class Blob2; template<typename T> bool operator==(const Blob<T> &, const Blob<T> &); template<typename T> class Blob2 { friend class BlobPtr<T>; friend bool operator==<T> (const Blob2<T> &, const Blob2<T> &); public: typedef T value_type; //using value_type=T; typedef typename vector<T>::size_type size_type; // using size_type=typename vector<T>::size_type; //构造函数 Blob2(); Blob2(initializer_list<T> il); //参数连串初始化 //元素个数 size_type size() const {return data->size();} //得到vector元素个数 bool empty() const {return data->empty();} //判断vector是否为空 //加减元素,拷贝 void push_back(const T &t) {data->push_back(t);} //移动版本,move,&&是右值引用!! void push_back(T &&t) { data->push_back(std::move(t));} void pop_back(); //删除一个元素 //元素调用 T &back(); //返回最后一个元素 T &operator[](size_type i); //下标运算符 private: shared_ptr<vector<T>> data; void check(size_type i, const string &msg) const; };
通用和特殊模板的友元
template<typename T> class Pal; class C //普通类 { friend class Pal<C>; //类 template<typename T> friend class Pal2; //申明友元不用前向申明 }; template<typename T> class C2 { friend class Pal<T>; template<typename X> friend class Pal2; friend class Pal3; };
Befriending the template own type parameter
template<typename Type> class Bar{friend Type;}; //这是新标准下可以这样 ///模板类型别名 template<typename T> using twin=pair<T, T>; void fun3() { twin<string> authors; twin<int> win_loss; twin<double> area; }
静态成员
template<typename T> class Foo { public: static size_t count() {return ctr;} private: static size_t ctr; }; template<typename T> size_t Foo<T>::ctr=0; void fun4() { Foo<int> fi; auto ct=Foo<int>::count(); ct=fi.count(); //Foo<int>::count // ct=Foo::count(); error:没有指定类型Foo<???> }
主函数
int main() { cout<<">>------------------------------fun1-----------------------------------<<"<<endl; fun1(); cout<<">>------------------------------fun2-----------------------------------<<"<<endl; fun2(); cout<<">>------------------------------fun3-----------------------------------<<"<<endl; fun3(); system("pause"); return 0; }
马上就要把C++primer结束了,感觉还是非常好的^_^,我决定了,这个月底吧这本书完全结束!!!
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。