模板特例化

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;

}

 

你可能感兴趣的:(模板)