给出实例化的定义。
用模板生成的class
或function
。
编写并测试你自己版本的
compare
函数。
template <typename T> int compare(const T &v1, const T &v2)
{
if (v1 < v2) return -1;
if (v2 < v1) return 1;
else return 0;
}
对两个
Sales_data
对象调用你的compare
函数,观察编译器在实例化过程中如何处理错误。
error C2678: binary '<': no operator found which takes a left-hand operand of type 'const Sales_data' (or there is no acceptable conversion)
编写行为类似标准库
find
算法的模板。函数需要两个模板类型参数,一个表示函数的迭代器参数,另一个表示值的类型,使用你的函数在一个vector<int>
和一个list<string>
中查找给定值。
see Find
为6.2.4节(第195页)中的
see Print
你认为接受一个数组实参的标准库函数
begin
和end
是如何工作的?定义你自己版本的begin
和end
。
see Begin&End
编写一个
constexpr
模板,返回给定数组的大小。
see sizeOfArray
在第97页的“关键概念”中,我们注意到,C++程序员喜欢使用
!=
而不喜欢<
。解释这个习惯的原因。
因为大多数迭代器都有==
和!=
运算符,而没有<
运算符,使用!=
就不必担心我们正在处理的容器的精确类型。
什么是函数模板?什么是类模板?
- 函数模板: 一个函数模板就是一个公式,可用来生成针对特定类型的函数版本。
- 类模板:类模板是用来生成类的蓝图的。
- 区别:编译器不能为类模板推断模板参数的类型。
当一个类模板被实例化时,会发生什么?
编译器将重写类模板,通过给定的模板参数替换模板参数T的每个实例。
下面的
List
定义是错误的。应如何修正它?
template <typename elemType> class ListItem;
template <typename elemType> class List {
public:
List<elemType>();
List<elemType>(const List<elemType> &);
List<elemType>& operator=(const List<elemType> &);
~List();
void insert(ListItem *ptr, elemType value);
private:
ListItem *front, *end;
};
实验类模板ListItem
时需要模板参数
void insert(ListItem<elemType> *ptr, elemType value);
ListItem<elemType> *front, *end;
编写你自己版本的
Blob
和BlobPtr
模板,包含书中未定义的多个const
成员。
see cpp | hpp | test 这里在编译的时候,出现无法解析的外部符号,解决方法戳这里。我使用第一种方案解决问题。
解释你为
BlobPtr
的相等和关系运算符选择哪种类型的友好关系?
对于每个BlobPtr
的实例,如果具有相同的类型,则为友好关系。
编写
Screen
类模板,用非类型参数定义Screen
的高和宽。
为你的
Screen
模板实现输入和输出运算符,Screen
类需要哪些友元(如果需要的话)来令输入和输出运算符正确工作?解释每个友元声明(如果有的话)为什么是必要的。
和Blob
是一样的。
将
StrVec
类重写为模板(参见13.5节,第465页),命名为Vec
。
声明为
typename
的类型参数和声明为class
的类型参数有什么不同(如果有的话)?什么时候必须使用typename
?
当我们想通知编译器一个名称代表一个类型时,我们必须使用关键字typename,而不是类。 看到一个比较好的说明http://blog.csdn.net/dick_china/article/details/4522253
解释下面每个函数模板声明并指出它们是否非法。更正你发现的每个错误。
(a) template <typename T, U, typename V> void f1(T, U, V);
(b) template <typename T> T f2(int &T);
(c) inline template <typename T> T foo(T, unsigned int*);
(d) template <typename T> f4(T, T);
(e) typedef char Ctype;
template <typename Ctype> Ctype f5(Ctype a);
更正
(a) template <typename T, typename U, typename V> void f1(T, U, V);
(b) template <typename T> T f2(int &);
编写函数,接受一个容器的引用,打印容器中的元素。使用容器的
size_type
和size
成员来控制打印元素的循环。
see cpp
重写上一题的函数,使用
begin
和end
返回的迭代器控制循环。
see cpp