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

目录
打赏
0
相关文章
c++模板进阶操作——非类型模板参数、模板的特化以及模板的分离编译
在 C++ 中,仿函数(Functor)是指重载了函数调用运算符()的对象。仿函数可以像普通函数一样被调用,但它们实际上是对象,可以携带状态并具有更多功能。与普通函数相比,仿函数具有更强的灵活性和可扩展性。仿函数通常通过定义一个包含operator()的类来实现。public:// 重载函数调用运算符Add add;// 创建 Add 类的对象// 使用仿函数return 0;
92 0
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
62 0
模板(C++)
本内容主要讲解了C++中的函数模板与类模板。函数模板是一个与类型无关的函数家族,使用时根据实参类型生成特定版本,其定义可用`typename`或`class`作为关键字。函数模板实例化分为隐式和显式,前者由编译器推导类型,后者手动指定类型。同时,非模板函数优先于同名模板函数调用,且模板函数不支持自动类型转换。类模板则通过在类名后加`&lt;&gt;`指定类型实例化,生成具体类。最后,语录鼓励大家继续努力,技术不断进步!
|
6月前
|
【c++】模板详解(2)
本文深入探讨了C++模板的高级特性,包括非类型模板参数、模板特化和模板分离编译。通过具体代码示例,详细讲解了非类型参数的应用场景及其限制,函数模板和类模板的特化方式,以及分离编译时可能出现的链接错误及解决方案。最后总结了模板的优点如提高代码复用性和类型安全,以及缺点如增加编译时间和代码复杂度。通过本文的学习,读者可以进一步加深对C++模板的理解并灵活应用于实际编程中。
86 0
深入理解C++模板编程:从基础到进阶
在C++编程中,模板是实现泛型编程的关键工具。模板使得代码能够适用于不同的数据类型,极大地提升了代码复用性、灵活性和可维护性。本文将深入探讨模板编程的基础知识,包括函数模板和类模板的定义、使用、以及它们的实例化和匹配规则。
㉿㉿㉿c++模板的初阶(通俗易懂简化版)㉿㉿㉿
㉿㉿㉿c++模板的初阶(通俗易懂简化版)㉿㉿㉿
【C++11】可变模板参数详解
本文详细介绍了C++11引入的可变模板参数,这是一种允许模板接受任意数量和类型参数的强大工具。文章从基本概念入手,讲解了可变模板参数的语法、参数包的展开方法,以及如何结合递归调用、折叠表达式等技术实现高效编程。通过具体示例,如打印任意数量参数、类型安全的`printf`替代方案等,展示了其在实际开发中的应用。最后,文章讨论了性能优化策略和常见问题,帮助读者更好地理解和使用这一高级C++特性。
284 4
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
134 0
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
134 12
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等