Template Parameter
#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;
}