模板特例化

简介: 16.62定义你自己版本的hash,并定义一个Sales_data对象的unordered_multiset。将多条交易记录保存到容器中,并打印其内容。 Sales_data.h #ifndef SALES_DATA_H #define SALES_DATA_H #include #i...

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;
}

 

相关文章
|
25天前
|
机器学习/深度学习 算法 编译器
【C++ 泛型编程 中级篇】深度解析C++:类型模板参数与非类型模板参数
【C++ 泛型编程 中级篇】深度解析C++:类型模板参数与非类型模板参数
46 0
|
7天前
|
存储 编译器 Linux
【C++初阶(十)】C++模板(进阶) ---非类型模板参数、模板的特化以及模板的分离编译
【C++初阶(十)】C++模板(进阶) ---非类型模板参数、模板的特化以及模板的分离编译
15 0
|
24天前
|
算法 编译器 C++
【C++ 模板编程 基础知识】C++ 模板类部分特例化的参数顺序
【C++ 模板编程 基础知识】C++ 模板类部分特例化的参数顺序
21 0
|
24天前
|
算法 搜索推荐 编译器
【C/C++ 编程题 04】实现 模板函数和模板类的特例化,并且展示差异化的点
【C/C++ 编程题 04】实现 模板函数和模板类的特例化,并且展示差异化的点
28 0
|
6月前
|
C语言 C++ 容器
【C++】模板进阶:非类型模板参数&模板的特化&模板分离编译(上)
【C++】模板进阶:非类型模板参数&模板的特化&模板分离编译(上)
|
6月前
|
编译器 C语言 C++
【C++】模板进阶:非类型模板参数&模板的特化&模板分离编译(下)
【C++】模板进阶:非类型模板参数&模板的特化&模板分离编译(下)
|
9月前
|
编译器 C# C++
C++11可变模版参数的妙用 typename... 三点解析
C++11可变模版参数的妙用 typename... 三点解析
141 0
|
11月前
|
编译器 C++
C++模板(函数模板,类模板)的基本使用与非类型模板参数与模板的特化(2)
C++模板(函数模板,类模板)的基本使用与非类型模板参数与模板的特化
104 0
|
11月前
|
编译器 C++
C++模板(函数模板,类模板)的基本使用与非类型模板参数与模板的特化(1)
我们先来思考一个问题,如果有人让你实现一个通用的交换函数你们会怎么做?有的小伙伴会说,我会使用函数重载的方式,把每一种类型重载,但…难道就没有更容易的办法,不用敲那么多次吗?ok,就来看看我们今天要介绍的模板,能很好的帮你解决这个问题。
121 0