练习16.62
定义你自己版本的hash<Sales_data>,并定义一个Sales_data对象的unordered_multiset。将多条交易记录保存到容器中, 并打印其内容。
解答:
这个参考书中的实现吧。
练习16.63
定义一个函数模板,统计一个给定值在一个vector中出现的次数。测试你的函数,分别传递给它一个double的vector,一个int的vector以及一个string的vector。
解答:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#define debug 0
namespace test{
template <typename T>
int count(const std::vector<T>& vec, const T& val){
#if debug
std::cout << "using test-count_if" << std::endl;
#endif
return std::count(vec.cbegin(), vec.cend(), val);
}
}
int main(){
double d = 1.2;
int i = 3;
std::string str = "two";
std::vector<double> dvec{1.1, 1.2, 1.4, 4.2, 5.3, 1.2, 1.1, 1.2, 1.4, 1.7};
std::vector<int> ivec{1,2,3,4,5,3,4,5,3,5,3,5,3};
std::vector<std::string> svec{"one", "two", "three", "four", "five", "six", "two", "three", "two"};
std::cout << d << " appear " << test::count(dvec, d) << " time(s) in devc." << std::endl;
std::cout << i << " appear " << test::count(ivec, i) << " time(s) in ivec." << std::endl;
std::cout << str << " appear " << test::count(svec, str) << " time(s) in svec." << std::endl;
}
练习16.64
为上一题中的模板编写特例化版本来处理vector<const char*>。编写程序使用这个特例化版本。
解答:
template<>
int count(const std::vector<const char*> &vec, const char* const &val){
#if debug
std::cout << "using test-count_if<cont char*>" << std::endl;
#endif
return std::count(vec.cbegin(), vec.cend(), val);
}
在上一题的基础上添加如上语句,再添加测试例即可。
练习16.65
在16.3节(第617页)中我们定义了两个重载的debug_rep版本,一个接受const char*参数,另一个接受char*参数。将这两个函数重写为特例化版本。
解答:
template<>
string debug_rep(const char* const& s){
string tmp = s;
return '"' + tmp + '"';
}
template<>
string debug_rep(char* const &s){
string tmp = s;
return '"' + tmp + '"';
}
练习16.66
重载debug_rep函数与特例化相比,有何优点和缺点?
解答:
对于这个理解,我用特例化的次数也不是很多,这里也不能从经验上说些什么了。
引用书中的一段话
【引用】两个函数具有相同个的参数列表,因此显然两者提供同样好的匹配。但是编译器会选择非模板版本。当存在多个同样好的函数模板时,编译器选择最特例化的版本,除与相同的原因,一个费末班函数比一个函数模板更好。
【引用】对于一个调用,如果一个非函数模板与一个函数模板提供同样好的匹配,则选择非模板版本。
练习16.67
定义特例化版本会影响debug_rep的函数匹配么?如果不影响,为什么?
解答:
一个特例化版本的本质是一个实例,而非函数的重载。因此,特例化不影响函数匹配。