
本文共 2910 字,大约阅读时间需要 9 分钟。
C++ 类模板基础进阶系列
类模板基础与实例化
类模板是一种强大的编程工具,能够通过模板参数的泛化和特化,减少代码的冗余,提高代码的可维护性和可扩展性。在 C++ 中,类模板的核心思想是通过定义模板参数,创建适用于不同数据类型的类实例。
模板参数的定义与使用
模板参数通常用 template <typename T>
的形式定义,T 表示一个模板参数,可以是任意的数据类型。例如,以下是一个简单的类模板定义:
#includeusing namespace std;namespace _nmsp1 { template class myvector { public: typedef T* myiterator; // 迭代器类型定义 myvector(); myvector(T tmpt) {} myvector& operator=(const myvector&); void myfunc() { cout << "myfunc()被调用" << endl; } static void mystaticfunc() { cout << "mystaticfunc()被调用" << endl; } myiterator mybegin(); myiterator myend(); }; template myvector ::myvector() {}}
类模板的实例化
类模板的实例化发生在以下两种情况:
class
后使用 <>
进行指定模板参数。例如: _nmsp1::myvector tmpvec;
_nmsp1::myvector tmpvec(12);
类模板的推断指南
在 C++ 17 中,推断指南(Deduction Guide)被进一步扩展,提供了更强大的模板参数推断能力。推断指南主要用于以下场景:
->
操作符,可以指导编译器如何从构造函数的参数推断模板参数。例如,以下是一个带有显式推断指南的类模板定义:
templatestruct A { A(T val1, T val2) {} A(T val) {}};template A(T, T) -> A ;
在这种情况下,调用 A aobj(15, 16)
时,编译器会根据构造函数的参数推断出 T
为 int
。
聚合类与推断指南
聚合类(Aggregate Class)是 C++ 中一个特殊的类模板,它允许用户直接访问成员变量,并且具有特殊的初始化语法。聚合类需要满足以下条件:
public
。推断指南的作用
推断指南对于聚合类尤为重要,因为它允许用户通过简洁的语法直接构造对象。例如:
templatestruct B { T m_b; T m_b2;};template B(T) -> B ;template B(T, U) -> B ;
在这种情况下,以下代码可以直接运行:
B bobj { 15 };B bobj2 { 15, 20 };
推断指南的应用
在没有自定义推断指南的情况下,用户需要显式地指定模板参数。例如:
_nmsp3::Bbobj3;_nmsp3::B bobj4;
通过定义自定义推断指南,可以简化代码,提高可读性。
类模板的特化与偏特化
类模板的特化(Specialization)是指对模板参数进行特定类型的定义,生成特化版本的类实例。特化可以分为两种形式:
例如,以下是一个模板参数范围上的偏特化:
templatestruct TC { T m_t; U m_u;};template struct TC;
在这种情况下,TC
只能接受指针类型的 U
。
全特化与偏特化的区别
全特化是对模板参数的全部定义生成特化版本,而偏特化只是对部分模板参数进行定义。全特化和偏特化可以结合使用,但需要注意顺序。例如:
templatestruct TC { TC() {} void functest();};template TC { TC() {} void functest();};
在这种情况下,TC<int, int*>
是一个全特化版本,TC<int, int>
是一个偏特化版本。
缺省参数与非类型模板参数
模板参数可以定义缺省值,减少用户的输入。缺省参数的定义遵循以下规则:
例如,以下是一个带有缺省参数的类模板定义:
templatestruct TC { TC() {} void functest();};
在这种情况下,TC()
的 T
和 U
都会被默认定义为 int
。
非类型模板参数
非类型模板参数通常用于接受编译时常量或静态数据。这些参数的类型通常是整数或指针。例如:
templatestruct TC { T m_arr[arrsize]; void functest();};
在这种情况下,arrsize
是一个非类型模板参数,T
是类型模板参数。
非类型模板参数的限制
非类型模板参数不能是浮点类型,因为它们需要在编译时确定大小。同时,全局指针和字符串常量不能作为非类型模板参数。
结论
类模板是 C++ 编程中的一个强大工具,它通过模板参数的泛化和特化,简化了代码的复杂性。通过合理使用推断指南、特化和缺省参数,可以进一步提高代码的可维护性和扩展性。了解和掌握类模板的使用,是一个每个 C++ 开发者必须掌握的核心技能。
发表评论
最新留言
关于作者
