定义一个模板
比较大小的函数如果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结束了,感觉还是非常好的^_^,我决定了,这个月底吧这本书完全结束!!!