《C++ Primer》第16章 16.3节习题答案

《C++ Primer》第16章 模板与泛型编程

16.3节 重载与模板 习题答案

练习16.48:编写你自己版本的debug_rep函数。

【出题思路】

理解模板重载。

【解答】

参考书中本节内容编写,与配套网站中的代码进行对照即可。尝试定义宏OVERCHAR(#define OVERCHAR)和SPECIALIZED(#define SPECIALIZED)来改变源码,重新编译运行程序,观察输出结果的差异(同时定义宏DEBUG,可以观察函数(模板)被调用的次序,更好地帮助你理解结果差异的原因)。例如,宏OVERCHAR只在SPECIALIZED未定义时起作用。程序总会定义接受string的非模板函数,若未定义OVERCHAR,则还会定义接受char *和const char*的非模板函数。因此,当未定义OVERCAR时,主程序中的

cout << debug_rep("hi") << endl;

会输出(打开了DEBUG):

const char * const string & "hi"

因为此时最佳匹配是接受const char *的非模板函数,它构造了一个string,继续调用debug_rep,因此又会匹配接受string的非模板函数。

std::string debug_rep(const char *p)
{
#ifdef DEBUG
	std::cout << "const chaar *" << "\t";
#endif
	return debug_rep(std::string(p));
}

而当定义OVERCHAR时,会输出:

T* const T& pointer: hi h

因为此时最佳匹配是接受T *的模板,它又调用debug_rep打印指针指向的值,又会匹配最通用的模板const T &。

template <typename T> std::string debug_rep(T *p)
{
#ifdef DEBUG
	std::cout << "T*" << "\t";
#endif
	std::ostringstream ret;
	ret << "pointer:" << p;//打印指针自己的值
	if(p)
		ret << " " << debug_rep(*p);//打印p指向的值
	else
		ret  << " null pointer";//p为空指针
	return ret.str();//返回打印出的内容(保存在ret的字符串中)
}

而当打开SPECIALIZED后,输出为:

const string & "hi"

原因是,打开SPECIALIZED后,不再定义非模板函数,而只会定义模板的特例化版本,此时最佳匹配是接受const string &的特例化版本:

template<> std::string debug_rep(const std::string &s)
#endif
{
#ifdef DEBUG
	std::cout << "const string &" << "\t";
#endif
	return '"' + s " '"';
}

读者可自行分析主程序中其他debug_rep调用输出的异同。

练习16.49:解释下面每个调用会发生什么:

template <typename T> void f(T);
template <typename T> void f(const T*);
template <typename T> void g(T);
template <typename T> void g(T*);
int i = 42, *p = &i;
const int ci = 0, *p2 = &ci;
g(42);    g(p);    g(ci);     g(p2);
f(42);     f(p);     f(ci);      f(p2);

【出题思路】

理解模板重载。

【解答】

g(42)匹配模板3,T被推断为int。

g(p)匹配模板4,T被推断为int。

g(ci)匹配模板3,T被推断为int。

g(p2)匹配模板4,T被推断为const int。

f(42)匹配模板1,T被推断为int。

f(p)匹配模板1,T被推断为int*。

f(ci)匹配模板1,T被推断为int。

f(p2)匹配模板2,T被推断为int。

练习16.50:定义上一个练习中的函数,令它们打印一条身份信息。运行该练习中的代码。如果函数调用的行为与你的预期不符,确定你理解了原因。

【出题思路】

理解模板重载。

【解答】

#include <iostream>
#include <typeinfo>

using std::cout;
using std::endl;

template <typename T>
void f(T a)
{
    cout << "f(T), T是" << typeid(T).name() << endl;
}

template <typename T>
void f(const T *a)
{
    cout << "f(const T*), const T*是" << typeid(const T*).name() << endl;
}

template <typename T> void g(T a)
{
    cout << "g(T*), T*是" << typeid(T*).name() << endl;
}

int main()
{
    int i = 42, *p = &i;
    const int ci = 0, *p2 = &ci;
    g(42);
    g(p);
    g(ci);
    g(p2);
    f(42);
    f(p);
    f(ci);
    f(p2);
    return 0;
}

运行结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值