MISAYAONE的博客

坚持、果敢、勤思、沉淀

C++Primer第五版 第十六章习题答案(61~67)

61:自己定义shared_ptr是不是在哪做过,忘了。


62:知识点1:当我们不能(或者不希望)使用模版版本时,我们可以定义类模版或者函数模版的一个特例化版本:比如说函数模版中的处理不适用于未定义<运算符(指针类型)的情况,我们就可以特例化一个版本已使用特殊情况

知识点2:一个特例化版本就是模版的一个独立的定义,在其中一个或者多个参数被特定为指定的类型

知识点3:在为函数模版特例化时,必须为函数模版的每个模版参数提供实参,尖括号中的模版参数去掉,但是必须提供实参

template <> int compare(const int&p1, const int&p2)
{
	//
}


知识点4:特例化的本质是实例化一个模版,而非重载,因此特例化不影响函数的重载,它不是一个非模版的独立函数

知识点5:模版及其特例化版本应该定义在一个头文件中,所有同名的模版的声明应该放在前面,然后是这些特例化的声明

知识点6:类模版也可以进行特例化,需要在原模版定义所在的命名空间中特例化,本节用例:hash模版所在命名空间为标准库std,所以我们可以打开标准空间对该命名空间添加成员:

Scales_data.h

#include <iostream>  
#include <string>  
class Sales_data  
{  
    std::string bookNo;  
    unsigned units_sold;  
    double revenue;  
    double avg_price()const { return units_sold ? revenue / units_sold : 0; }  
public:  
    Sales_data(const std::string &s=std::string(), unsigned n = 0, double p = 0) :bookNo(s), units_sold(n), revenue(p) {}  
    Sales_data(std::istream &is);  
    std::string isbn()const { return bookNo; }  
    Sales_data &operator+=(const Sales_data &s);  
    friend std::hash<Sales_data>;  
    friend std::ostream &operator<<(std::ostream &os, const Sales_data &s);  
    friend std::istream &operator>>(std::istream &is, Sales_data &s);  
    friend bool operator==(const Sales_data &ls, const Sales_data &rs);  
    friend Sales_data operator+(const Sales_data &ls, const Sales_data &rs);  
    friend std::ostream &print(std::ostream &os, const Sales_data &s);  
    friend std::istream &read(std::istream &is, Sales_data &s);  
};  
bool operator!=(const Sales_data &ls, const Sales_data &rs);  
Sales_data add(const Sales_data &ls, const Sales_data &rs);  
  
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 {  
            return hash<string>()(s.bookNo) ^ hash<unsigned>()(s.units_sold) ^ hash<double>()(s.revenue);  
        }  
    };  
}  

Scales_data.cpp

#include "Sales_data.h"  
  
Sales_data::Sales_data(std::istream &is)  
{  
    is >> *this;  
}  
  
Sales_data &Sales_data::operator+=(const Sales_data &s)  
{  
    units_sold += s.units_sold;  
    revenue += s.revenue;  
    return *this;  
}  
  
std::ostream &operator<<(std::ostream &os, const Sales_data &s)  
{  
    os << s.isbn() << " " << s.units_sold << " " << s.revenue << " " << s.avg_price();  
    return os;  
}  
  
std::istream &operator>>(std::istream &is, Sales_data &s)  
{  
    double price;  
    is >> s.bookNo >> s.units_sold >> price;  
    if (is)  
        s.revenue = s.units_sold*price;  
    else  
        s = Sales_data();  
    return is;  
}  
  
bool operator==(const Sales_data &ls, const Sales_data &rs)  
{  
    return ls.bookNo == rs.bookNo&&ls.units_sold == rs.units_sold&&ls.revenue == rs.revenue;  
}  
bool operator!=(const Sales_data &ls, const Sales_data &rs)  
{  
    return !(ls == rs);  
}  
  
Sales_data operator+(const Sales_data &ls, const Sales_data &rs)  
{  
    Sales_data temp = ls;  
    temp += rs;  
    return temp;  
}  
  
Sales_data add(const Sales_data &ls, const Sales_data &rs)  
{  
    Sales_data temp = ls;  
    temp += rs;  
    return temp;  
}  
  
std::ostream &print(std::ostream &os, const Sales_data &s)  
{  
    os << s.isbn() << " " << s.units_sold << " " << s.revenue << " " << s.avg_price();  
    return os;  
}  
  
std::istream &read(std::istream &is, Sales_data &s)  
{  
    double price;  
    is >> s.bookNo >> s.units_sold >> price;  
    s.revenue = s.units_sold*price;  
    return is;  
}  

main.cpp

#include <memory>  
#include <unordered_set>  
#include "Sales_data.h"  
  
int main()  
{  
    //! test for ex16.62  
    std::unordered_multiset<Sales_data> mset;  
    Sales_data sd("Bible", 10, 0.98);  
  
    mset.emplace(sd);  
    mset.emplace("C++ Primer", 5, 9.99);  
  
    for (const auto &item : mset)  
        std::cout << "the hash code of " << item.isbn()  
        << ":\n0x" << std::hex << std::hash<Sales_data>()(item)  
        << "\n";  
    system("pause");  
    return 0;  
}  

62:

show_times.h

#ifndef SHOW_TIMES_H
#define SHOW_TIMES_H

template<typename T, typename U> int show_times(const T& vec,const U& val)
{
	int showtimes = 0;
	for (size_t i = 0; i < vec.size(); ++i)
	{
		if(vec[i] == val)
		{
			++showtimes;
		}
	}
	return showtimes;
}
#endif SHOW_TIMES_H

main.cpp

/***************************************************************************
 *  @file       main.cpp
 *  @author     MISAYAONE
 *  @date       17  March 2017
 *  @remark     17  March 2017 
 ***************************************************************************/

#include <iostream>
#include <vector>
#include <list>
#include <string>
#include "show_times.h"
using namespace std;

int main(int argc,char** argv)
{
	vector<int> vec1;
	vec1.push_back(1);
	vec1.push_back(2);
	int a = 1;
	cout<<a<<"出现次数为:"<<show_times(vec1,a)<<endl;

	vector<double> vec2;
	vec2.push_back(1.2);
	vec2.push_back(2.4);
	double b = 1.2;
	cout<<b<<"出现次数为:"<<show_times(vec2,b)<<endl;

	vector<string> vec3;
	vec3.push_back(string("123"));
	vec3.push_back(string("23"));
	string c = "123";
	cout<<c<<"出现次数为:"<<show_times(vec3,c)<<endl;
	cin.get();
	return 0;
}


63:知识点1:可以使用strcmp函数比较两个字符指针,若两字符串相等,返回0

#ifndef SHOW_TIMES_H
#define SHOW_TIMES_H

template<typename T>int show_times(const std::vector<T> &vec,const T val)
{
	int showtimes = 0;
	for (size_t i = 0; i < vec.size(); ++i)
	{
		if(vec[i] == val)
		{
			++showtimes;
		}
	}
	return showtimes;
}

//特例化char*
template<>int show_times(const std::vector<char *> &vec,char *val)
{
	int showtimes = 0;
	for (size_t i = 0; i < vec.size(); ++i)
	{
		if(strcmp(vec[i], val))
		{
			++showtimes;
		}
	}
	return showtimes;
} 
#endif SHOW_TIMES_H

/***************************************************************************
 *  @file       main.cpp
 *  @author     MISAYAONE
 *  @date       17  March 2017
 *  @remark     17  March 2017 
 ***************************************************************************/

#include <iostream>
#include <vector>
#include <list>
#include <string>
#include "show_times.h"
using namespace std;

int main(int argc,char** argv)
{
	vector<int> vec1;
	vec1.push_back(1);
	vec1.push_back(2);
	int a = 1;
	cout<<a<<"出现次数为:"<<show_times(vec1,a)<<endl;

	vector<double> vec2;
	vec2.push_back(1.2);
	vec2.push_back(2.4);
	double b = 1.2;
	cout<<b<<"出现次数为:"<<show_times(vec2,b)<<endl;

	vector<string> vec3;
	vec3.push_back(string("123"));
	vec3.push_back(string("23"));
	string c = "123";
	cout<<c<<"出现次数为:"<<show_times(vec3,c)<<endl;

	vector<char*> vec4;
	vec4.push_back("1230");
	vec4.push_back("123");
	char *d = "1230";
	cout<<d<<"出现次数为:"<<show_times<char *>(vec4,"1230")<<endl;//这里需要指定说明符

	cin.get();
	return 0;
}


65:

template<typename T>  
std::string debug_rep(T *t)  
{  
    std::ostringstream ret;  
    ret << t;  
    return ret.str();  
}  
template<>  
std::string debug_rep(char *t)  
{  
    return std::string(t);  
}  
template<>  
std::string debug_rep(const char *t)  
{  
    return std::string(t);  
}  


66:重载会改变匹配优先度,而特例化则不会


67:不会影响,特例化的模板匹配优先度和模板级别一致


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/misayaaaaa/article/details/62898729
个人分类: 【C++Primer习题】
想对作者说点什么? 我来说一句

c++primer第五版中文版练习题答案

2014年10月15日 3.01MB 下载

c++primer第五版习题答案(全)

2015年08月19日 374KB 下载

没有更多推荐了,返回首页

不良信息举报

C++Primer第五版 第十六章习题答案(61~67)

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭