#include<iostream> #include<algorithm> #include<memory> #include<list> #include<fstream> #include<string> using namespace std; template<typename Foo> Foo calc(const Foo &a, const Foo &b) { Foo temp=a; //... return temp; } ///Template Parameters and Scope 模板参数和作用域 typedef double A; template<typename A, typename B> void f(A a, B b) { A tmp=a; // double B; error:模板类型B,B是一个类型不是一个参数 } ///template Declarations 模板声明 template<typename T> int compare(const T &, const T &); template<typename T> class Blob; ///使用类成员类型 template<typename T> //T可以是一个类类型 typename T::value_type //可以类似这个样得到类的值,这是一个返回类型 top(const T &c) { if(!c.empty()) return c.back(); else return typename T::value_type(); } /* 如果我们想要那个模板里的名字是一个类型,不是!!注意用的是“不是”,不是类class的 话,那么必须用typename来修饰,而不是class */ ///Default Template Arguments 默认模板参数 template<typename T, typename F=less<T>> //F默认为一个函数 int compare(const T &v1, const T &v2, F f=F()) //就是less<T>() { if(f(v1, v2)) return -1; if(f(v2, v1)) return 1; return 0; } ///模板默认参数和类模板 template<class T=int> //这个int 就是T的默认类型 class Numbers { public: Numbers(T v=0):val(v) {} private: T val; }; void fun1() { Numbers<long double> lots_of_precisions; Numbers<> average_precisions; } /************************************** 模板成员 **************************************/ class DebugDelete { public: DebugDelete(ostream &s=cerr):os(s) {} //不论任何函数模板,T的类型由编译器自行推导 template<typename T> void operator()(T* p) const {os<<"deleting unique_ptr "<<endl; delete p;} private: ostream& os; }; void fun2() { double* p=new double; DebugDelete d; //d默认对象 d(p); //--->delete p; int* ip=new int; DebugDelete() (ip); unique_ptr<string, DebugDelete> sp(new string, DebugDelete()); } /* void DebugDelete::operator()(int* p) const {delete p;} void DebugDelete::operator()(string* p) const {delete p;} 这两个就是上面那个过程的不用模板,类里面就要这样写 */ ///模板类里面的成员模板 template<typename> class BlobPtr; template<typename> class Blob; template<typename T> bool operator==(const Blob<T> &, const Blob<T> &); template<typename T> class Blob { friend class BlobPtr<T>; friend bool operator==<T> (const Blob<T> &, const Blob<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; //构造函数 template<typename It> Blob(It b, It e); 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> template<typename It> Blob<T>::Blob(It b, It e):data(make_shared<vector<T>>(b, e)){} ///成员模板实例化 void fun3() { int ia[]={0,1,2,3,4,5,6,7,8,9}; vector<long> vi={0,1,2,3,4,5,6,7,8,9}; list<const char*> w={"now","is","the","time"}; Blob<int> a1(begin(ia), end(ia)); Blob<int> a2(vi.begin(), vi.end()); Blob<string> a3(w.begin(), w.end()); } /************************************** 16.2模板参数推演 **************************************/ ///转化和模板类型参数 template<typename T> T fobj(T a, T b){cout<<"template<typename T> T fobj(T, T)"<<endl; return a;} template<typename T> T fref(const T &a, const T &b){cout<<"template<typename T> T fref(const T &, const T &)"<<endl; return b;} void fun4() { string s1("a value"); const string s2("another value"); cout<<"fobj(s1, s2) s1:"<<fobj(s1, s2)<<endl; //注意返回类型!!! cout<<"fref(s1, s2) s2:"<<fref(s1, s2)<<endl; int a[10], b[42]; cout<<"fobj(a, b); a:"<<fobj(a,b)<<endl; // fref(a, b); error:这是&引用,而a,b是int *一个指针 } ///函数的参数使用相同的模板形参类型 template<typename A, typename B> int flexibleCompare(const A &v1, const B &v2) { if(v1<v2) return -1; if(v2<v1) return 1; return 0; } void fun5() { long lng=1111.0; cout<<"flexibleCompare(lng, 1024):"<<flexibleCompare(lng, 1024)<<endl; } template<typename T> ostream &print(ostream &os, const T &obj) {return os<<obj<<endl;} void fun6() { print(cout, 42); ofstream f1("output.txt"); print(f1, 10); } /************************************** 函数模板的显示实参 **************************************/ ///指定一个显示形参 template<typename T1, typename T2, typename T3> T1 sum(T2, T3){} void fun7() { int i; long lng; auto val3=sum<long long>(i, lng); } /* 只有确定返回类型后才可自行推导,如果只是知道后面几个类型那就没法推导了 说的是<long long >里面的类型,是第一个 */ /** 尾返回类型和类型转换 */ template<typename It> auto fcn(It beg, It end) -> decltype(*beg) { return *beg; } int main() { cout<<">>------------------------------fun1-----------------------------------<<"<<endl; fun1(); cout<<">>------------------------------fun2-----------------------------------<<"<<endl; fun2(); cout<<">>------------------------------fun3-----------------------------------<<"<<endl; fun3(); cout<<">>------------------------------fun4-----------------------------------<<"<<endl; fun4(); cout<<">>------------------------------fun5-----------------------------------<<"<<endl; fun5(); cout<<">>------------------------------fun6-----------------------------------<<"<<endl; fun6(); cout<<">>------------------------------fun7-----------------------------------<<"<<endl; fun7(); system("pause"); return 0; }
【足迹C++primer】58、Template Parameter,布布扣,bubuko.com
【足迹C++primer】58、Template Parameter
原文:http://blog.csdn.net/cutter_point/article/details/38310853