练习16.1:
实例化:当我们调用一个函数模板时,编译器(通常)用函数实参来为我们推断模板实参
练习16.2:
#include <iostream>
#include <vector>
using namespace std;
template<typename T> int compare(const T& v1, const T& v2)
{
if (less<T>()(v1, v2))return -1;
if (less<T>()(v2, v1))return 1;
return 0;
}
int main()
{
vector<int>vec1{ 1,2,3 }, vec2{ 4,5,6 }, vec3{ 1,2,3 };
cout << compare(vec1, vec2) << endl;
cout << compare(vec1, vec3) << endl;
system("pause");
return 0;
}
测试:
练习16.3:
测试代码如下:
#include <iostream>
#include <vector>
using namespace std;
template<typename T> int compare(const T& v1, const T& v2)
{
if (less<T>()(v1, v2))return -1;
if (less<T>()(v2, v1))return 1;
return 0;
}
class Sales_date {
public:
//默认构造函数
Sales_date() :bookNo(std::string()) { }
Sales_date(const std::string& s, unsigned us, double p) :bookNo(s), units_sold(us), revenue(p* us) { }
Sales_date(const std::string& s) :bookNo(s) { }
//拷贝构造函数
Sales_date(const Sales_date& s) :bookNo(s.bookNo), units_sold(s.units_sold), revenue(s.revenue) { }
//拷贝赋值运算符
Sales_date& operator=(const Sales_date&);
//得到bookNo
std::string isbn()const { return bookNo; }
private:
//平均售价
double avg_price()const { return units_sold ? revenue / units_sold : 0; }
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
int main()
{
Sales_date s1("hello");
Sales_date s2("world");
cout << compare(s1, s2) << endl;
system("pause");
return 0;
}
此时编译器并未报错,运行,实例化,发生错误,未定义Sales_date的小于符号
练习16.4:
将算法命名为findValue,代码如下:
#include <iostream>
#include <vector>
#include <list>
using namespace std;
template<typename T,typename N>
T findValue(const T& v1, const T& v2, const N& v3)
{
auto it = v1;
for (; it != v2; ++it)
{
if (*it == v3)
{
break;
}
}
return it;
}
int main()
{
//测试vector<int>
vector<int>v = { 1,2,4,7,9,16,88,26,8 };
auto beg1 = v.begin(), end1 = v.end();
auto result = findValue(beg1, end1, 10);
if (result == end1)
{
cout << "vector<int>: value is not exist" << endl;
}
else
{
cout << "vector<int>: find it!!!" << endl;
}
//测试list<string>
list<string>ls = { "hello","C++","you","are","great" };
auto beg2 = ls.begin(), end2 = ls.end();
auto rs = findValue(beg2, end2, "are");
if (rs == end2)
{
cout << "list<string>: value is not exist" << endl;
}
else
{
cout << "list<string>: find it!!!" << endl;
}
system("pause");
return 0;
}
测试结果:
练习16.5:
#include <iostream>
#include <vector>
#include <list>
using namespace std;
//print
template<typename T, unsigned N>
void print(const T(&v)[N])
{
for (auto elem : v)
{
cout << elem << " ";
}
cout << endl;
}
int main()
{
//测试
//int数组
int a[] = { 0,1,2,3,4,5,6,7,8,9 };
print(a);
//double数组
double b[] = { 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7 };
print(b);
//string数组
char c[] = "hello world!!!";
print(c);
system("pause");
return 0;
}
结果如下:
练习16.6:
与迭代器类似, begin返回指向数组首元素的指针,end返回指向数组尾后元素的指针,代码如下:
#include <iostream>
#include <vector>
#include <list>
using namespace std;
//print
template<typename T, unsigned N>
T* begin(const T(&v)[N])
{
return &v[0];
}
template<typename T, unsigned N>
T* end(const T(&v)[N])
{
return &v[N];
}
int main()
{
//测试
//int数组
int a[] = { 0,1,2,3,4,5,6,7,8,9 };
for (auto it = begin(a); it != end(a); ++it)
{
cout << *it << " ";
}
cout << endl;
cout << endl;
//double数组
double b[] = { 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7 };
for (auto it = begin(b); it != end(b); ++it)
{
cout << *it << " ";
}
cout << endl;
cout << endl;
//string数组
char c[] = "hello world!!!";
for (auto it = begin(c); it != end(c); ++it)
{
cout << *it << " ";
}
cout << endl;
system("pause");
return 0;
}
测试结果为:
练习16.7:
下列代码定义了数组所占字节大小
#include <iostream>
#include <vector>
#include <list>
using namespace std;
//print
template<typename T, unsigned N>constexpr
size_t arraySize(const T(&v)[N])
{
return N * sizeof(T);
}
int main()
{
int a[] = { 0,1,2,3,4,5,8,7,8,9 };
char c[] = { 'a','b','c','d','e','f','g' };
cout << arraySize(a) << endl;
cout << arraySize(c) << endl;
system("pause");
return 0;
}
结果为:
练习16.8:
主要是为了让代码的可用性更高。在 STL 中,所有的迭代器都支持!=操作,但是只有随机迭代器支持<操作