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

原创 2017年03月18日 09:29:48

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:不会影响,特例化的模板匹配优先度和模板级别一致


版权声明:本文为博主原创文章,未经博主允许不得转载。

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

51:知识点1:可变函数模版就是指一个接受可变数目参数的模版函数或者模版类,可变数目的参数被称为参数包,分为两种:模版参数包,表示零个或多个模版参数,函数参数包,表示零个或多个函数参数 知识点2:C+...
  • misayaaaaa
  • misayaaaaa
  • 2017年03月18日 09:29
  • 1502

c++primer第五版第十六章练习

16.1 根据模板参数的类型实例化出一个该类型的函数 16.2 #include #include #include //less //#include "../../7.21/7.21/标...
  • nonororo
  • nonororo
  • 2016年04月09日 23:35
  • 4354

C++Primer第五版——习题答案+详解(完整版)

C++Primer第五版——习题答案详解       看的也比较快,但是有很多东西确实用不上,所以很多都没有深入的探讨,但是知识点覆盖的很全面,每一道题涉及的知识点我都写上简单的解释了。      ...
  • misayaaaaa
  • misayaaaaa
  • 2016年12月21日 16:11
  • 49671

C++Primer 中文版 第五版 第四章课后习题答案

前言:自己做的,如果有错误,要提出来哟... //4.1 105 //4.2 *(vec.begin()); *(vec.begin())+1; //4.3 可以接受..利大于弊嘛....
  • Little_boy_z
  • Little_boy_z
  • 2016年06月03日 18:24
  • 873

c++ primer第五版(中文)习题答案 第一章-开始

本博客知识记录自己学习中的笔记或者记录,如果有错误欢迎大家纠正。 写完第十章习题,开始从头开始,把前面的习题全部完成,书也顺序看下去。习题解答 1.1 查阅你使用的编译器的文档,确定它所使用的文件命...
  • xhxwd
  • xhxwd
  • 2015年10月22日 22:12
  • 7152

C++Primer 中文版 第五版 第三章课后习题答案

前言:自己做的,如果有错误,要提出来哟... //3.1 略 //3.2 /* #include using namespace std; int main() {   ...
  • Little_boy_z
  • Little_boy_z
  • 2016年06月03日 18:23
  • 1365

c++primer(第五版) 第十一章 关联容器习题答案

纯原创    转载请注明出处:http://blog.csdn.net/axuan_k 11.1    11.2     11.4 #include #include #inc...
  • AXuan_K
  • AXuan_K
  • 2016年03月07日 12:57
  • 1209

C++ Primer 中文版(第五版)课后题答案 事前说明

老师一直让我在csdn上做一个东西,具体什么东西都可以。我左思右想,决定先从身边的开始入手。那就是C++Primer这本书,刚开学学习的时候,从网上搜答案,怎么都搜不到,现在就服务人民,自己发一份答案...
  • Little_boy_z
  • Little_boy_z
  • 2016年06月01日 14:59
  • 584

C++Primer 中文版 第五版 第七章课后习题答案

//7.1 #include #include using namespace std; struct Sales_data { string bookNo; unsigned unit...
  • Little_boy_z
  • Little_boy_z
  • 2016年06月08日 20:07
  • 1710

C++Primer中文(第五版)习题答案(英文)

----------------------- Page 1-----------------------       Answers For Programming Exercises in C...
  • u012432785
  • u012432785
  • 2016年08月01日 10:57
  • 792
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++Primer第五版 第十六章习题答案(61~67)
举报原因:
原因补充:

(最多只允许输入30个字)