首页 > 代码库 > 模板特例化

模板特例化

16.62定义你自己版本的hash<Sales_data>,并定义一个Sales_data对象的unordered_multiset。将多条交易记录保存到容器中,并打印其内容。

Sales_data.h

#ifndef SALES_DATA_H#define SALES_DATA_H#include<iostream>#include<string>using namespace std;//template <typename T> class std::hash;class Sales_data{    friend class std::hash<Sales_data>;    friend Sales_data add(const Sales_data&,const Sales_data&);    friend istream &read(istream&,Sales_data &);    friend ostream &print(ostream&,const Sales_data&);    friend ostream& operator<<(ostream&,const Sales_data&);    friend istream& operator>>(istream&,Sales_data&);    friend Sales_data operator+(const Sales_data&,const Sales_data&);public:    //构造函数    Sales_data() {cout<<"=default"<<endl;}    Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n) {cout<<"construct"<<endl;}    Sales_data(istream&);    //成员函数    string isbn() const { return bookNo;}    Sales_data &combine(const Sales_data&);    double avg_price() const;    //拷贝构造函数    Sales_data(const Sales_data&);    //析构函数    ~Sales_data() { cout<<"destructor"<<endl;}    Sales_data& operator+=(const Sales_data&);    Sales_data& operator=(string);    operator string() const {return bookNo;}    operator double() const {return revenue;}private:    string bookNo;    unsigned units_sold=0;    double revenue=0.0;};Sales_data add(const Sales_data&,const Sales_data&);istream &read(istream &,Sales_data&);ostream &print(ostream&,const Sales_data&);ostream& operator<<(ostream&,const Sales_data&);istream& operator>>(istream&,Sales_data&);Sales_data operator+(const Sales_data&,const Sales_data&);namespace std{    template<>    struct hash<Sales_data>    {        typedef size_t result_type;        typedef Sales_data argument_type;        size_t operator()(const Sales_data &s) const;    };}#endif

Sales_data.cpp

#include"Sales_data.h"Sales_data add(const Sales_data &lhs,const Sales_data &rhs){    Sales_data sum=lhs;    sum.combine(rhs);    return sum;}istream &read(istream &is,Sales_data &item){    double price=0;    is>>item.bookNo>>item.units_sold>>price;    item.revenue=price*item.units_sold;    return is;}ostream &print(ostream &os,const Sales_data &item){    os<<item.isbn()<<" "<<item.units_sold<<" "<<item.revenue<<" "<<item.avg_price();    return os;}Sales_data::Sales_data(istream& is){    read(is,*this);}Sales_data& Sales_data::combine(const Sales_data& rhs){    units_sold+=rhs.units_sold;    revenue+=rhs.revenue;    return *this;}double Sales_data::avg_price() const{    if(units_sold)        return revenue/units_sold;    else        return 0;}Sales_data::Sales_data(const Sales_data &orig):bookNo(orig.bookNo),units_sold(orig.units_sold),revenue(orig.revenue){    cout<<"copy construct"<<endl;}ostream& operator<<(ostream &os,const Sales_data &item){    os<<item.isbn()<<" "<<item.units_sold<<" "<<item.revenue<<" "<<item.avg_price();    return os;}istream& operator>>(istream &is,Sales_data &item){    double price;    is>>item.bookNo>>item.units_sold>>price;    if(is)        item.revenue=item.units_sold*price;    else        item=Sales_data();    return is;}Sales_data& Sales_data::operator+=(const Sales_data &rhs){    units_sold+=rhs.units_sold;    revenue+=rhs.revenue;    return *this;}Sales_data operator+(const Sales_data &lhs,const Sales_data &rhs){    Sales_data sum=lhs;    sum+=lhs;    return sum;}Sales_data& Sales_data::operator=(string s){    bookNo=s;    return *this;}namespace std{    size_t hash<Sales_data>::operator()(const Sales_data &s) const    {        return hash<string>()(s.bookNo)^hash<unsigned>()(s.units_sold)^hash<double>()(s.revenue);    }}

main.cpp

#include"Sales_data.h"#include<vector>#include<unordered_set>bool fcn(const Sales_data *trans,Sales_data accum){    Sales_data item1(*trans),item2(accum);    return item1.isbn()!=item2.isbn();}template <typename T>int compare(const T &lhs,const T &rhs){    if(lhs<rhs) return -1;    if(rhs<lhs) return 1;    return 0;}int main(){    string ss="fd";    ss=="fd";    vector<Sales_data> vec;    Sales_data s={"sa",7,2};    cout<<endl;    //Sales_data *p=new Sales_data();    Sales_data s1=s;    Sales_data s2(s);    s=s1;    cout<<endl;    //fcn(&s,s1);    cout<<"vector"<<endl;    vec.push_back(s);    vec.push_back(s1);    //vec.push_back(s2);    cout<<endl;    //delete p;    cout<< compare<Sales_data>(Sales_data(),s2)<<endl;    cout<<"unordered_multiset"<<endl;    unordered_multiset<Sales_data> SDset;    while(cin>>s)        SDset.insert(s);    SDset.insert(s);    SDset.insert(s1);    SDset.insert(s2);    cout<<SDset.size()<<endl;    for(auto a:SDset)        cout<<a<<endl;    return 0;}

16.63定义一个函数模板,统计一个给定值在一个vector中出现的次数。测试你的函数,分别传递给它一个double的vector,一个int的vector以及一个string的vector。

#include<iostream>#include<string>#include<vector>#include<algorithm>using namespace std;template <typename T>int count1(vector<T> &v,T value){    int Count=0;    Count=count(v.begin(),v.end(),value);    return Count;}template<>int count1(vector<const char *> &v,const char* value){    cout<<"const char *"<<endl;    int Count=0;    Count=count(v.begin(),v.end(),value);    return Count;}int main(){    vector<double> dvec={1.2,34.2,4,5.2,34.5};    vector<int> ivec={1,3,4,5,6,7,8,9,0};    vector<string> svec={"a","b","c","d","e","f"};    vector<const char*> cvec={"a","b","c","d","e","f"};    cout<<count1(dvec,5.3)<<endl;    cout<<count1(ivec,5)<<endl;    cout<<count1<string>(svec,("a"))<<endl;    cout<<count1(cvec,"b")<<endl;}

 

模板特例化