28、C++ Primer 4th 笔记,模板与泛型编程(3)-阿里云开发者社区

开发者社区> hopegrace> 正文

28、C++ Primer 4th 笔记,模板与泛型编程(3)

简介: 1、用const char*实参调用如下模板,则比较的是指针值,而不是指向的字符串。此时需要模板特化。 示例 template int compare(const T &v1, const T &v2) { if (v1 < v2) return -1; if (v2 < v1) return 1; return 0; } 2、函数模板的特化:一个或多个模板形参的实际类型或实际值是指定的。
+关注继续查看

1、用const char*实参调用如下模板,则比较的是指针值,而不是指向的字符串。此时需要模板特化。

示例

template <typename T>
int compare(const T &v1, const T &v2)
{
	if (v1 < v2) return -1;
	if (v2 < v1) return 1;
	return 0;
}

2、函数模板的特化:一个或多个模板形参的实际类型或实际值是指定的。

• 关键字 template 后面接一对空的尖括号(<>);

• 再接模板名和一对尖括号,尖括号中指定这个特化定义的模板形参;

• 函数形参表;

• 函数体。

示例代码

// special version of compare to handle C-style character strings
template <>
int compare<const char*>(const char* const &v1,
						 const char* const &v2)
{
	return strcmp(v1, v2);
}

特化的声明必须与对应的模板相匹配。

1)、与任意函数一样,函数模板特化可以声明而无须定义。

示例

// declaration of function template explicit specialization
template<>
int compare<const char*>(const char* const&,
						 const char* const&);

2)、省略template<>则结果是声明该函数的重载非模板版本。

示例

// generic template definition
template <class T>
int compare(const T& t1, const T& t2) { /* ... */ }
// OK: ordinary function declaration
int compare(const char* const&, const char* const&);

当定义非模板函数的时候,对实参应用常规转换,当特化模板的时候,对实参类型不应用转换。

3)、如果程序由多个文件构成,模板特化的声明必须在使用该特化的每个文件中出现。

3、类模板的特化

示例

/* definition of specialization for const char*
* this class forwards its work to Queue<string>;
* the push function translates the const char* parameter to a string
* the front functions return a string rather than a const char*
*/
template<> 
class Queue<const char*> 
{
public:
	// no copy control: Synthesized versions work for this class
	// similarly, no need for explicit default constructor either
	void push(const char*);
	void pop() {real_queue.pop();}
	bool empty() const {return real_queue.empty();}
	// Note: return type does not match template parameter type
	std::string front() {return real_queue.front();}
	const std::string &front() const
	{return real_queue.front();}
private:
	Queue<std::string> real_queue; // forward calls to real_queue
};

void Queue<const char*>::push(const char* val)
{
	return real_queue.push(val);
}

    在类特化外部定义成员时,成员之前不能加 template<> 标记。

1)除了特化整个类模板之外,还可以只特化成员,但是成员特化的声明与任何其他函数模板特化一样,必须以空的模板形参表开头。

示例

template<>
void Queue<const char*>::push(const char* const&);

2)类模板的部分特化

类模板的部分特化本身也是模板。编译器将为实例化选择最特化的模板定义。

示例

template <class T1, class T2>
class some_template {
// ...
};
// partial specialization: fixes T2 as int and allows T1 to vary
template <class T1>
class some_template<T1, int> {
// ...
};

some_template<int, string> foo; // uses template
some_template<string, int> bar; // uses partial specialization

4、重载与函数模板

函数模板可以重载:可以定义有相同名字但形参数目或类型不同的多个函数模板,也可以定义与函数模板有相同名字的普通非模板函数。

普通函数优先于模板版本。当匹配同样好时,非模板版本优先。

5、函数模板是建立算法库的基础,类模板是建立标准库容器和迭代器的基础。

6、几个关键概念:

1)泛型句柄类:保存和管理指向其他类的指针的类。泛型句柄接受单个类型形参,并且分配和管理指向该类型对象的指针。句柄类定义了必要的复制控制成员,*,->操作符。不需要了解它管理的类型。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《C Primer Plus》读书笔记——递归
递归的原理 一个函数调用其本身,此调用过程为递归(recursion)。 递归的使用 举个栗子: /*用来测试UpAndDown函数的驱动程序*/ #include void UpAndDown (int); int main(void) { UpAnd...
925 0
UNIX环境高级编程笔记之高级I/O
  本章说明了很多高级I/O功能: 非阻塞I/O——发一个I/O操作,不使其阻塞,记录锁,STREAMS机制 I/O多路转接——select和poll函数 readv和writev函数,以及存储映射I/O(mmap函数)
700 0
UNIX环境高级编程笔记之线程
  本章涉及到线程的一些基本知识点,讨论了现有的创建线程和销毁线程的POSIX.1原语,此外,重点介绍了线程同步问题,讨论了三种基本的同步机制:互斥量、读写锁、条件变量。
551 0
Java之网络编程笔记
网络通讯要素: 1.IP地址     IP地址:用于标记一台计算机的身份证。 IP地址由网络地址(确定网络)和主机地址(网络中的主机)组成。             IP地址分为A类地址、B类地址、C类地址(常用)、D类地址、E类地址。
712 0
UNIX环境高级编程笔记之进程控制
  本章重点介绍了进程控制的几个函数:fork、exec族、_exit、wait和waitpid等,主要需要掌握的是父进程和子进程之间的运行机制,怎么处理进程的正常和异常终止、以及怎么让进程执行不同的程序等知识点。下一章将进一步说明一个进程和其他进程之间的关系——会话和作业控制。
676 0
+关注
698
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载