模板的特化与偏特化
c++11函数模板“偏特化”的一种实现
c++11函数模板“偏特化”的⼀种实现c++11模板的偏特化仅限于类模板,对于函数模板的偏特化,就需要借助std::enable_if类⾃动去编译enbale通过的函数。
问题描述:实现⼀个插值模板,把光滑阶数作为模板参数,实现1阶光滑的插值和2阶连续的插值。
template<typename type, unsigned int smoothness = 1>typename enable_if<smoothness == 1, type>::typeinterpolate(const type& a, const type& b, const type& x){return x < a ? 0 : (x > b ? 1 : (x - a) / (b - a));}template<typename type, unsigned int smoothness>typename enable_if<smoothness == 2, type>::typeinterpolate(const type& a, const type& b, const type& x){auto y = (x - a) / (b - a);return y < 0 ? 0 : (y > 1 ? 1 : y * y * (static_cast<type>(3) - static_cast<type>(2) * y));}另⼀种应⽤是函数需要对整型和浮点型有不同的实现⽅式,也可以使⽤std::enable_if 和类型判别模板is_floating_point和is_integral实现。
template<typename type>typename std::enable_if<std::is_floating_point<type>::value, void>::typeprint(const type& value){cout<<"floating:"<<value<<endl;}template<typename type>typename std::enable_if<std::is_integral<type>::value, void>::typeprint(const type& value){cout<<"integral:"<<value<<endl;}。
C++进阶课程计划
C++进阶课程计划一、课程简介C++是一种广泛使用的编程语言,具有高效、灵活和跨平台的特点。
本课程旨在帮助学员深入理解C++的高级特性和编程技巧,提升编程能力和解决问题的能力。
通过本课程的学习,学员将掌握C++模板、STL、并发编程、性能优化等高级知识,并能够运用这些知识解决实际问题。
二、课程目标1. 掌握C++模板编程,包括函数模板、类模板、模板元编程等。
2. 熟练使用C++标准模板库(STL),包括容器、迭代器、算法和函数对象。
3. 理解并发编程的基本概念,掌握C++11之后的并发编程特性,如线程、互斥量、条件变量等。
4. 学习C++性能优化技巧,提高程序的运行效率。
5. 提升编程能力和解决问题的能力。
三、课程内容3.1 模板编程- 函数模板- 类模板- 模板元编程3.2 STL- 容器:向量、列表、队列、栈、映射、集合等- 迭代器- 算法:排序、查找、替换、转换等- 函数对象:比较函数、谓词、函数适配器等3.3 并发编程- 线程:创建、销毁、线程同步等- 互斥量:互斥锁、递归锁、死锁避免等- 条件变量:条件等待、通知等- 原子操作和内存模型3.4 性能优化- 编译器优化选项- 代码分析工具:如Valgrind、Gprof等- 性能瓶颈分析与优化- 内存管理:动态内存分配、智能指针等四、课程安排4.1 模板编程(2周)- 第1周:函数模板、类模板基础- 第2周:模板元编程、模板特化与偏特化4.2 STL(3周)- 第3周:容器与迭代器- 第4周:STL算法- 第5周:STL函数对象与适配器4.3 并发编程(3周)- 第6周:线程基础与同步- 第7周:互斥量与条件变量- 第8周:原子操作与内存模型4.4 性能优化(2周)- 第9周:编译器优化选项- 第10周:代码分析与性能瓶颈分析五、课程评价课程结束后,将对学员进行考核,包括以下几个方面:1. 模板编程:编写一个模板函数,实现两个数组的排序。
c++ template 用法
C++ Template 用法1. 概述C++ 是一种功能强大的编程语言,而 Template 是 C++ 中一个非常重要的特性。
Template 的使用可以帮助我们编写更加通用、灵活的代码,提高代码的复用性和可维护性。
在本文中,我们将介绍 C++ Template 的基本语法和常见用法,帮助读者更好地理解和使用Template。
2. Template 的基本语法Template 是一种泛型编程的重要手段,通过 Template 可以编写不特定类型的代码。
在 C++ 中,我们可以使用 Template 来实现类模板和函数模板。
2.1 类模板类模板可以让我们编写不特定类型的类,其基本语法如下:```cpptemplate <class T>class MyTemplate {// 类的成员和方法};```在上面的代码中,`template <class T>` 声明了一个模板,`T` 是一个类型参数,表示我们可以在实例化 MyTemplate 类时传入不同的类型。
2.2 函数模板函数模板可以让我们编写不特定类型的函数,其基本语法如下:```cpptemplate <class T>T MyFunction(T a, T b) {// 函数体}```在上面的代码中,`template <class T>` 声明了一个模板,`T` 是一个类型参数,表示我们可以在调用 MyFunction 函数时传入不同的类型。
3. Template 的特化和偏特化在实际使用过程中,有时候我们需要针对特定类型进行定制化的处理,这时可以使用 Template 的特化和偏特化。
3.1 特化Template 的特化是指对某个特定的类型进行定制化的处理,其基本语法如下:```cpptemplate <>class MyTemplate<int> {// 类的成员和方法};```在上面的代码中,`template <>` 表示这是对特定类型的特化处理,`int` 表示需要特化的类型。
c++ template 实现原理
c++ template 实现原理C++模板是一种编程工具,它可以在编译时进行泛型编程。
它允许我们在代码中定义一种通用的类型或算法,使其适用于多种不同的类型,而无需为每种新类型编写新的代码。
C++模板的实现原理可以分为两个阶段:实例化和实例化后的代码生成。
在实例化阶段,编译器扫描模板代码,找到模板声明,并根据模板被调用时的参数类型,生成模板实例。
例如,假设我们有一个模板函数add,并在代码中调用该函数add<int>(2, 3)。
在实例化阶段,编译器会根据模板函数add的定义,生成一个具有int类型参数的实例。
这个过程称为模板实例化。
在实例化后的代码生成阶段,编译器会根据生成的模板实例,生成对应的函数或类代码。
这些代码与普通的函数或类定义具有相同的形式,只是参数类型被模板参数替代。
生成的代码会被链接器处理,以生成最终的可执行文件。
C++模板的实现原理依赖于编译器的支持。
在编译器实现中,有两种常见的模板实现方法:编译时生成和二次编译。
编译时生成是指编译器在实例化阶段直接将模板代码转换为对应的实例代码。
在这种实现方法中,编译器会在模板被调用时生成对应的实例代码,并将其插入到编译单元中。
这种方法的优点是生成的代码效率高,缺点是编译时间可能会增长,特别是当模板被多次实例化时。
二次编译是指编译器在生成模板实例后,使用实例化后的代码进行二次编译。
在这种实现方法中,编译器会将模板实例生成为中间表示形式,然后在实例化完成后,将中间表示形式作为输入,生成对应的机器代码。
这种方法的优点是编译时间快,缺点是生成的代码可能会比编译时生成的代码效率低一些。
无论是编译时生成还是二次编译,模板实例化都是通过对模板参数类型进行替换来完成的。
编译器会根据调用模板时的参数类型,在模板代码中进行相应的替换。
这个过程称为模板参数推导。
模板参数推导是通过编译器进行类型推导来实现的。
编译器会根据模板代码和调用代码中的参数类型,推导出模板参数的具体类型。
C++模板编程中只特化模板类的一个成员函数
C++模板编程中只特化模板类的⼀个成员函数模板编程中如果要特化或偏特化(局部特化)⼀个类模板,需要特化该类模板的所有成员函数。
类模板中⼤多数成员函数的功能可能是⼀模⼀样的,特化时我们可能只需要重新实现1、2个成员函数即可。
在这种情况下,如果全部重写该模板类的所有成员函数,不但会增加⼯作量,也不利于代码的维护。
例如下⾯的类模板A,只有在模板参数是char*时才需要特化成员函数func(),但其他的成员函数都不需要特化:1 template <typename _Ty>2 struct A3 {4 // 其他成员函数a5 // 其他成员函数b6 // ......7 void func()8 {9 std::cout << "common type." << std::endl;10 }11 };1213 int main()14 {15 A<int> i;16 i.func();1718 A<char*> c;19 c.func();2021 return 0;22 }⽅法⼀:通过运⾏时类型识别,这个⽅法最简单1 template <typename _Ty>2 struct A3 {4 // 其他成员函数a5 // 其他成员函数b6 // ......7 void func()8 {9 if (typeid(_Ty) == typeid(char*))10 std::cout << "common type." << std::endl;11 else12 std::cout << "special type." << std::endl;13 }14 };⽅法⼆:通过类的成员函数模板特化来实现,这个⽅法也⽐较简单1 template <typename _Ty>2 struct A3 {4 // 其他成员函数a5 // 其他成员函数b6 // ......7 template <typename __Ty>8 void funcImpl()9 {10 std::cout << "common type." << std::endl;11 }1213 template <>14 void funcImpl<char*>()15 {16 std::cout << "special type." << std::endl;17 }1819 void func()20 {21 funcImpl<_Ty>();22 }23 };⽅法三:通过⼀个嵌套模板类的特化来实现1 template <typename _Ty>2 struct A3 {4 // 其他成员函数a5 // 其他成员函数b6 // ......7 template <typename __Ty>8 struct IsCharPType9 {10 const static bool b = false;11 };1213 template<>14 struct IsCharPType<char*>15 {16 const static bool b = true;17 };1819 void func()20 {21 if (IsCharPType<_Ty>::b)22 std::cout << "special type." << std::endl;23 else24 std::cout << "common type." << std::endl;25 }26 };⽅法四:先定义⼀个嵌套的类模板,通过重载函数实现(函数的参数类型不同)1 template <typename _Ty>2 struct A3 {4 // 其他成员函数a5 // 其他成员函数b6 // ......7 template <typename __Ty>8 struct TypeClass9 {10 };1112 template <typename __Ty>13 void funcImpl(const TypeClass<__Ty>&)14 {15 std::cout << "common type." << std::endl;16 }1718 void funcImpl(const TypeClass<char*>&)19 {20 std::cout << "special type." << std::endl;21 }2223 void func()24 {25 funcImpl(TypeClass<_Ty>());26 }27 };。
模板函数偏特化
模板函数偏特化C++中的模板函数可以进行特化,即当某些参数具有特定的类型时,编译器会优先选择特化的函数,而不选择普通的模板函数。
而函数模板偏特化则是在模板参数中固定一部分参数的类型,只保留另一部分参数的通用类型,在编译时根据传入的实参进行推导。
函数模板偏特化的语法如下:```c++。
template <typename T, typename U>。
void foo(T t, U u)。
//通用模板函数。
}。
template <typename T>。
void foo<T, int>(T t, int u)。
// 偏特化模板函数,其中第二个参数的类型被固定为int。
}。
template <typename T>。
void foo<T, double>(T t, double u)。
// 偏特化模板函数,其中第二个参数的类型被固定为double。
}。
```。
在上述代码中,`foo`为一个函数模板,接收两个参数,分别为类型为`T`和`U`的实参。
我们在后面分别定义了两个函数模板的偏特化版本:第一个参数为`T`,第二个参数为`int`的版本,以及第一个参数为`T`,第二个参数为`double`的版本。
当我们调用`foo`函数时,编译器将根据传入的实参类型来推导出使用哪个版本的偏特化函数。
举个例子,我们有如下代码:```c++。
int a = 1;。
double b = 1.0;。
foo(a, 1); // 调用偏特化版本 foo<T, int>(T t, int u)。
foo(b, 1.0); // 调用偏特化版本 foo<T, double>(T t, double u)。
foo("hello", false); // 调用通用模板函数 foo(T t, U u)。
```。
值得注意的是,函数模板偏特化仅仅是针对某一部分参数进行特化,而不是所有参数。
c++类模板函数模板的问题,模板函数不能是虚函数,虚函数不能是内联
c++类模板函数模板的问题,模板函数不能是虚函数,虚函数不能是内联内联函数不能为虚函数,原因在于虚表机制需要⼀个真正的函数地址,⽽内联函数展开以后,就不是⼀个函数,⽽是⼀段简单的代码,可能有些内联函数会⽆法内联展开,⽽编译成为函数虚函数不能模板化编译器在编译⼀个类的时候,需要确定这个类的虚函数表的⼤⼩。
⼀般来说,如果⼀个类有N个虚函数,它的虚函数表的⼤⼩就是N,如果按字节算的话那么就是4*N。
如果允许⼀个成员模板函数为虚函数的话,因为我们可以为该成员模板函数实例化出很多不同的版本,也就是可以实例化出很多不同版本的虚函数,那么编译器为了确定类的虚函数表的⼤⼩,就必须要知道我们⼀共为该成员模板函数实例化了多少个不同版本的虚函数。
显然编译器需要查找所有的代码⽂件,才能够知道到底有⼏个虚函数,这对于多⽂件的项⽬来说,代价是⾮常⾼的,所以规定成员模板函数不能够为虚函数。
那么编译器在编译Func类的时候,需要查看int mian ⾥⾯的具体调⽤,才知道会产⽣两个虚函数。
⼀个是virtual int Add (const int &a, const int &b); 另⼀个是 virtual double Add (const double &a, const double &b)。
当项⽬很⼤,⽂件特别多的时候,需要遍历完所有的⽂件才能确定实际会产⽣多少虚函数,所以这样编译的效率会⾮常的低。
因此规定成员模板函数不能够为虚函数最近要修改⼀个模板类的功能,对于特定形式的参数,想要复⽤函数名,进⼊不同的路径,于是就想到了模板函数偏特化举个例⼦#include <iostream>using namespace std;template <class T>class A{public:template <class T2>void Func(T2 t) { cout << t; } //成员函数模板template <>void Func<int>(int t) { cout << t; } //特化int};int main(){A<int> a;a.Func('K'); //成员函数模板Func被实例化a.Func("hello");return0;}此处遇到了⼏个问题1.类模板的模板函数,必须要在类内部定义,不然在外部template都不知道是类的还是函数的如果相对只想对模板类的某个函数偏特化,要⽤以下写法template<typename DataKey, typename Data>class CTemplateReportDataBaseMgr{public:bool print1(Data out_map_report_data,std::vector<DataKey>& in_vt_data_key) ;};template<typename DataKey, typename Data>bool CTemplateReportDataBaseMgr<DataKey, Data>::print1(Data out_map_report_data,std::vector<DataKey>& in_vt_data_key){return true;};template<>bool CTemplateReportDataBaseMgr<class DataKey,int>::print1( //注意这⾥的写法,不能直接像偏特化类⼀样的写法int out_map_report_data,std::vector<DataKey>& in_vt_data_key){return true;};类的模板特化写法template<typename T1,typename T2>class Test{public:Test(T1 i,T2 j):a(i),b(j){cout<<"模板类"<<endl;}private:T1 a;T2 b;};template<> //全特化,由于是全特化,参数都指定了,参数列表故为空。
c++ template 面试题
c++ template 面试题以下是一些关于C++模板的常见面试问题,以及它们的简要答案:1. 什么是C++模板?- C++模板是一种用于创建通用函数或类的工具,允许编写代码而不必指定特定的数据类型。
2. 什么是函数模板?-函数模板是一种用于创建通用函数的机制,允许函数操作不同类型的数据。
3. 什么是类模板?-类模板是一种用于创建通用类的机制,允许类操作不同类型的数据。
4. 什么是模板参数?-模板参数是在模板定义中使用的占位符,用于指定类型、值或模板。
5. 什么是模板特化?-模板特化是指针对特定类型或值的模板实例化,允许为特定类型或值提供定制的实现。
6. 什么是模板偏特化?-模板偏特化是指对模板中的一部分参数进行特化,通常用于处理特定类型或值的情况。
7. 什么是模板元编程?-模板元编程是一种利用模板和编译时计算来执行计算和生成代码的技术。
8. 什么是SFINAE(Substitution Failure Is Not An Error)?- SFINAE是一种C++编译器的行为,当模板实例化失败时,它不会报告错误,而是会尝试其他实例化。
9. 什么是可变参数模板?-可变参数模板是一种允许模板接受任意数量和类型参数的模板。
10. 什么是模板元素?-模板元素是一种允许在编译时进行计算和操作的类型或值。
11. 什么是模板实例化?-模板实例化是指在使用模板时,编译器根据具体的类型或值生成实际的函数或类的过程。
12. 什么是模板参数包展开?-模板参数包展开是指在可变参数模板中展开参数包,允许对参数包中的每个参数执行操作。
13. 什么是模板元编程中的递归?-模板元编程中的递归是指使用模板来实现递归算法,允许在编译时进行递归计算。
14. 什么是模板元编程中的模板特化?-模板元编程中的模板特化是指为特定类型或值提供定制的模板实现,允许在编译时处理特定情况。
15. 什么是模板元编程中的编译时条件判断?-模板元编程中的编译时条件判断是指使用模板来在编译时进行条件判断和分支选择。
C++模板之隐式实例化、显示实例化、隐式调用、显示调用和模板特化详解
C++模板之隐式实例化、显⽰实例化、隐式调⽤、显⽰调⽤和模板特化详解模板的实例化指函数模板(类模板)⽣成模板函数(模板类)的过程。
对于函数模板⽽⾔,模板实例化之后,会⽣成⼀个真正的函数。
⽽类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调⽤时才会被初始化。
模板的实例化分为隐式实例化和显⽰实例化。
对函数模板的使⽤⽽⾔,分为两种调⽤⽅式,⼀种是显⽰模板实参调⽤(显⽰调⽤),⼀种是隐式模板实参调⽤(隐式调⽤)。
对于类模板的使⽤⽽⾔,没有隐式模板实参和显式模板实参使⽤的说法,因为类模板的使⽤必须显⽰指明模板实参。
各个概念请勿混淆。
1.隐式实例化1.1模板隐式实例化的定义这是相对于模板显⽰实例化⽽⾔。
在使⽤模板函数和模板类时,不存在指定类型的模板函数和模板类的实体时,由编译器根据指定类型参数隐式⽣成模板函数或者模板类的实体称之为模板的隐式实例化。
1.2函数模板隐式实例化函数模板隐式实例化指的是在发⽣函数调⽤的时候,如果没有发现相匹配的函数存在,编译器就会寻找同名函数模板,如果可以成功进⾏参数类型推演,就对函数模板进⾏实例化。
还有⼀种简介调⽤函数的情况,也可以完成函数模板的实例化。
所谓的简介调⽤是指将函数⼊⼝地址传给⼀个函数指针,通过函数指针完成函数调⽤。
如果传递给函数指针不是⼀个真正的函数,那么编译器就会寻找同名的函数模板进⾏参数推演,进⽽完成函数模板的实例化。
参考如下⽰例。
#include <iostream>using namespace std;template <typename T> void func(T t){cout<<t<<endl;}void invoke(void (*p)(int)){int num=10;p(num);}int main(){invoke(func);}程序成功运⾏并输出10。
1.3类模板隐式实例化类模板隐式实例化指的是在使⽤模板类时才将模板实例化,相对于类模板显⽰实例化⽽⾔的。
c++模板 面试题
在C++面试中,模板是经常会考到的一个重要知识点。
下面列举几个常见的C ++模板相关的面试题,并进行详细分析:1.什么是C++模板?o分析:C++模板是一种编译时多态机制,允许程序员定义泛化的类或函数,可以处理多种数据类型。
通过模板,可以编写一次代码并应用于多种不同的类型上,避免了代码重复。
2.模板函数和模板类的声明与定义如何写?o分析:cpp// 模板函数声明template <typename T>T max(T a, T b) {return (a > b) ? a : b;}// 模板类声明template <typename T>class MyClass {T data;public:void setData(T value) { data = value; }T getData() const { return data; }};// 需要在源文件中提供相应的模板实例化(对于非inline函数和成员函数)template <>int max<int>(int a, int b); // 特化版本// 或者显式实例化所有需要的类型template class MyClass<int>;template class MyClass<double>;3.特例化(Specialization)和偏特化(Partial Specialization)的区别是什么?o分析:▪特例化:针对某个特定类型完全重新定义模板的行为,例如为max函数提供一个专门处理char类型的实现。
cpptemplate <>char max<char>(char a, char b) {// 特殊逻辑}▪偏特化:当模板参数是一个模板或者有多个参数时,对部分参数进行特化,而不是全部。
例如对模板类MyClass进行偏特化处理,假设当T为指针类型时,提供特殊实现。
c语言new C++的new
c语言new:C++的new“new”是C++的一个关键字,同时也是操作符。
关于new的话题非常多,因为它确实比较复杂,也非常神秘,下面我将把我了解到的与new有关的内容做一个总结。
new的过程当我们使用关键字new在堆上动态创建一个对象时,它实际上做了三件事:获得一块内存空间、调用构造函数、返回正确的指针。
当然,如果我们创建的是简单类型的变量,那么第二步会被省略。
假如我们定义了如下一个类A:class A{int i;public:A(int _i) :i(_i*_i) {}void Say() { printf("i=%dn", i); }};//调用new:A* pa = new A(3);那么上述动态创建一个对象的过程大致相当于以下三句话(只是大致上):A* pa = (A*)malloc(sizeof(A));pa->A::A(3);return pa;虽然从效果上看,这三句话也得到了一个有效的指向堆上的A对象的指针pa,但区别在于,当malloc失败时,它不会调用分配内存失败处理程序new_handler,而使用new的话会的。
因此我们还是要尽可能的使用new,除非有一些特殊的需求。
new的三种形态到目前为止,本文所提到的new都是指的“new operator”或称为“new expression”,但事实上在C++中一提到new,至少可能代表以下三种含义:new operator、operator new、placement new。
new operator就是我们平时所使用的new,其行为就是前面所说的三个步骤,我们不能更改它。
但具体到某一步骤中的行为,如果它不满足我们的具体要求时,我们是有可能更改它的。
三个步骤中最后一步只是简单的做一个指针的类型转换,没什么可说的,并且在编译出的代码中也并不需要这种转换,只是人为的认识罢了。
但前两步就有些内容了。
new operator的第一步分配内存实际上是通过调用operator new来完成的,这里的new实际上是像加减乘除一样的操作符,因此也是可以重载的。
C++中的模板元编程技术
C++中的模板元编程技术模板元编程(Template Metaprogramming)是C++中的一种高级编程技术,它能够在编译期间实现代码的生成和计算。
通过使用模板元编程技术,我们可以在编译器内部进行复杂的元操作,从而实现静态多态性和编译期计算等功能。
C++的模板元编程技术的核心概念是模板。
模板可以看作是一种通用的代码模型,里面可以包含一些类型和值的参数。
通过指定这些参数,我们可以生成一系列具体的代码,从而实现代码的复用和泛化。
模板元编程就是把这些泛化的代码编写成一些递归的结构,通过递归的展开,最后生成具体的代码。
模板元编程的核心思想是基于模板的编译期计算。
在C++中,模板元编程主要通过递归的方式来实现编译期计算。
通过特化模板和模板实例化的特性,我们可以在编译期间进行条件判断、循环等算法,从而在编译阶段就得到结果。
在模板元编程中,最常见的技术是使用模板特化和偏特化(Template Specialization)来实现编译期条件判断。
通过模板特化,我们可以为不同的类型提供不同的实现代码。
这样一来,根据不同的类型参数,编译器会在编译期间选择相应的代码路径。
使用模板特化,我们可以实现各种复杂的条件分支和多态性。
除了模板特化,模板元编程还可以使用模板递归技术来实现编译期循环。
通过递归展开模板,我们可以在编译期间进行循环计算。
然后,通过递归调用模板自身,不断展开模板,直到达到某个终止条件为止。
这样一来,我们可以实现各种需要循环计算的算法。
在模板元编程中,由于编译器的强大优化能力,能够在编译期间进行大量的优化计算。
相比于运行时的计算,编译期计算能够显著地提高代码的性能和效率。
而且,编译期计算也可以带来更灵活的代码生成能力,从而实现更多的功能和扩展性。
模板元编程在C++标准库中有广泛的应用。
比如,标准容器库中的各种算法和迭代器都是通过模板元编程实现的。
模板元编程技术还可以用于编写各种元函数库,从而实现一些通用的计算和转换操作。
泛化之美--C++11可变模版参数的妙用
泛化之美--C++11可变模版参数的妙⽤1概述C++11的新特性--可变模版参数(variadic templates)是C++11新增的最强⼤的特性之⼀,它对参数进⾏了⾼度泛化,它能表⽰0到任意个数、任意类型的参数。
相⽐C++98/03,类模版和函数模版中只能含固定数量的模版参数,可变模版参数⽆疑是⼀个巨⼤的改进。
然⽽由于可变模版参数⽐较抽象,使⽤起来需要⼀定的技巧,所以它也是C++11中最难理解和掌握的特性之⼀。
虽然掌握可变模版参数有⼀定难度,但是它却是C++11中最有意思的⼀个特性,本⽂希望带领读者由浅⼊深的认识和掌握这⼀特性,同时也会通过⼀些实例来展⽰可变参数模版的⼀些⽤法。
2可变模版参数的展开可变参数模板和普通模板的语义是⼀样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后⾯带上省略号“...”。
⽐如我们常常这样声明⼀个可变模版参数:template<typename...>或者template<class...>,⼀个典型的可变模版参数的定义是这样的:template <class... T>void f(T... args); 上⾯的可变模版参数的定义当中,省略号的作⽤有两个:1.声明⼀个参数包T... args,这个参数包中可以包含0到任意个模板参数;2.在模板定义的右边,可以将参数包展开成⼀个⼀个独⽴的参数。
上⾯的参数args前⾯有省略号,所以它就是⼀个可变模版参数,我们把带省略号的参数称为“参数包”,它⾥⾯包含了0到N(N>=0)个模版参数。
我们⽆法直接获取参数包args中的每个参数的,只能通过展开参数包的⽅式来获取参数包中的每个参数,这是使⽤可变模版参数的⼀个主要特点,也是最⼤的难点,即如何展开可变模版参数。
可变模版参数和普通的模版参数语义是⼀致的,所以可以应⽤于函数和类,即可变模版参数函数和可变模版参数类,然⽽,模版函数不⽀持偏特化,所以可变模版参数函数和可变模版参数类展开可变模版参数的⽅法还不尽相同,下⾯我们来分别看看他们展开可变模版参数的⽅法。
编程术语英语翻译
编程术语英语翻译abstract 抽象的抽象的abstraction 抽象体、抽象物、抽象性抽象体、抽象物、抽象性access 存取、取用存取、访问access level 存取级别访问级别access function 存取函式访问函数activate 活化激活active 作用中的adapter 配接器适配器address 位址地址address space 位址空间,定址空间address-of operator 取址运算子取地址操作符aggregation 聚合algorithm 演算法算法allocate 配置分配allocator (空间)配置器分配器application 应用程式应用、应用程序application framework 应用程式框架、应用框架应用程序框架architecture 架构、系统架构体系结构argument 引数(传给函式的值)。
叁见 parameter 叁数、实质叁数、实叁、自变量array 阵列数组arrow operator arrow(箭头)运算子箭头操作符assembly 装配件assembly language 组合语言汇编语言assert(ion) 断言assign 指派、指定、设值、赋值赋值assignment 指派、指定赋值、分配assignment operator 指派(赋值)运算子 = 赋值操作符associated 相应的、相关的相关的、关联、相应的associative container 关联式容器(对应 sequential container)关联式容器atomic 不可分割的原子的attribute 属性属性、特性audio 音讯音频A.I. 人工智慧人工智能background 背景背景(用於图形着色)後台(用於行程)backward compatible 回溯相容向下兼容bandwidth 频宽带宽base class 基础类别基类base type 基础型别 (等同於 base class)batch 批次(意思是整批作业)批处理benefit 利益收益best viable function 最佳可行函式最佳可行函式(从 viable functions 中挑出的最佳吻合者)binary search 二分搜寻法二分查找binary tree 二元树二叉树binary function 二元函式双叁函数binary operator 二元运算子二元操作符binding 系结绑定bit 位元位bit field 位元栏位域bitmap 位元图位图bitwise 以 bit 为单元逐一┅bitwise copy 以 bit 为单元进行复制;位元逐一复制位拷贝block 区块,区段块、区块、语句块boolean 布林值(真假值,true 或 false)布尔值border 边框、框线边框brace(curly brace) 大括弧、大括号花括弧、花括号bracket(square brakcet) 中括弧、中括号方括弧、方括号breakpoint 中断点断点build 建造、构筑、建置(MS 用语)build-in 内建内置bus 汇流排总线business 商务,业务业务buttons 按钮按钮byte 位元组(由 8 bits 组成)字节cache 快取高速缓存call 呼叫、叫用调用callback 回呼回调call operator call(函式呼叫)运算子调用操作符(同 function call operator)candidate function 候选函式候选函数(在函式多载决议程序中出现的候选函式)chain 串链(例 chain of function calls)链character 字元字符check box 核取方块 (i.e. check button) 复选框checked exception 可控式异常(Java)check button 方钮 (i.e. check box) 复选按钮child class 子类别(或称为derived class, subtype)子类class 类别类class body 类别本体类体class declaration 类别宣告、类别宣告式类声明class definition 类别定义、类别定义式类定义class derivation list 类别衍化列类继承列表class head 类别表头类头class hierarchy 类别继承体系, 类别阶层类层次体系class library 类别程式库、类别库类库class template 类别模板、类别范本类模板class template partial specializations类别模板偏特化类模板部分特化class template specializations类别模板特化类模板特化cleanup 清理、善後清理、清除client 客端、客户端、客户客户client-server 主从架构客户/服务器clipboard 剪贴簿剪贴板clone 复制克隆collection 群集集合combo box 复合方块、复合框组合框command line 命令列命令行(系统文字模式下的整行执行命令)communication 通讯通讯compatible 相容兼容compile time 编译期编译期、编译时compiler 编译器编译器component 组件组件composition 复合、合成、组合组合computer 电脑、计算机计算机、电脑concept 概念概念concrete 具象的实在的concurrent 并行并发configuration 组态配置connection 连接,连线(网络,资料库)连接constraint 约束(条件)construct 构件构件container 容器容器(存放资料的某种结构如 list, vector...)containment 内含包容context 背景关系、周遭环境、上下脉络环境、上下文control 控制元件、控件控件console 主控台控制台const 常数(constant 的缩写,C++ 关键字)constant 常数(相对於 variable)常量constructor(ctor)建构式构造函数(与class 同名的一种 member functions)copy (v) 复制、拷贝拷贝copy (n) 复件, 副本cover 涵盖覆盖create 创建、建立、产生、生成创建creation 产生、生成创建cursor 游标光标custom 订制、自定定制data 资料数据database 资料库数据库database schema 数据库结构纲目data member 资料成员、成员变数数据成员、成员变量data structure 资料结构数据结构datagram 资料元数据报文dead lock 死结死锁debug 除错调试debugger 除错器调试器declaration 宣告、宣告式声明deduction 推导(例:template argument deduction)推导、推断default 预设缺省、默认defer 延缓推迟define 定义预定义definition 定义、定义区、定义式定义delegate 委派、委托、委任委托delegation (同上)demarshal 反编列散集dereference 提领(取出指标所指物体的内容)解叁考dereference operator dereference(提领)运算子 * 解叁考操作符derived class 衍生类别派生类design by contract 契约式设计design pattern 设计范式、设计样式设计模式※ 最近我比较喜欢「设计范式」一词destroy 摧毁、销毁destructor 解构式析构函数device 装置、设备设备dialog 对话窗、对话盒对话框directive 指令(例:using directive) (编译)指示符directory 目录目录disk 碟盘dispatch 分派分派distributed computing 分布式计算 (分布式电算) 分布式计算分散式计算 (分散式电算)document 文件文档dot operator dot(句点)运算子 . (圆)点操作符driver 驱动程式驱动(程序)dynamic binding 动态系结动态绑定efficiency 效率效率efficient 高效高效end user 终端用户entity 物体实体、物体encapsulation 封装封装enclosing class 外围类别(与巢状类别 nested class 有关)外围类enum (enumeration) 列举(一种 C++ 资料型别)枚举enumerators 列举元(enum 型别中的成员)枚举成员、枚举器equal 相等相等equality 相等性相等性equality operator equality(等号)运算子 == 等号操作符equivalence 等价性、等同性、对等性等价性equivalent 等价、等同、对等等价escape code 转义码转义码evaluate 评估、求值、核定评估event 事件事件event driven 事件驱动的事件驱动的exception 异常情况异常exception declaration 异常宣告(ref. C++ Primer 3/e, 11.3)异常声明exception handling 异常处理、异常处理机制异常处理、异常处理机制exception specification 异常规格(ref. C++ Primer 3/e, 11.4)异常规范exit 退离(指离开函式时的那一个执行点)退出explicit 明白的、明显的、显式显式export 汇出引出、导出expression 运算式、算式表达式facility 设施、设备设施、设备feature 特性field 栏位,资料栏(Java)字段, 值域(Java)file 档案文件firmware 韧体固件flag 旗标标记flash memory 快闪记忆体闪存flexibility 弹性灵活性flush 清理、扫清刷新font 字型字体form 表单(programming 用语)窗体formal parameter 形式叁数形式叁数forward declaration 前置宣告前置声明forwarding 转呼叫,转发转发forwarding function 转呼叫函式,转发函式转发函数fractal 碎形分形framework 框架框架full specialization 全特化(ref. partial specialization)function 函式、函数函数function call operator 同 call operatorfunction object 函式物件(ref. C++ Primer 3/e, 12.3)函数对象function overloaded resolution函式多载决议程序函数重载解决(方案)functionality 功能、机能功能function template 函式模板、函式范本函数模板functor 仿函式仿函式、函子game 游戏游戏generate 生成generic 泛型、一般化的一般化的、通用的、泛化generic algorithm 泛型演算法通用算法getter (相对於 setter) 取值函式global 全域的(对应於 local)全局的global object 全域物件全局对象global scope resolution operator全域生存空间(范围决议)运算子 :: 全局范围解析操作符group 群组group box 群组方块分组框guard clause 卫述句 (Refactoring, p250) 卫语句GUI 图形介面图形界面hand shaking 握手协商handle 识别码、识别号、号码牌、权柄句柄handler 处理常式处理函数hard-coded 编死的硬编码的hard-copy 硬拷图屏幕截图hard disk 硬碟硬盘hardware 硬体硬件hash table 杂凑表哈希表、散列表header file 表头档、标头档头文件heap 堆积堆hierarchy 阶层体系层次结构(体系)hook 挂钩钩子hyperlink 超链结超链接icon 图示、图标图标IDE 整合开发环境集成开发环境identifier 识别字、识别符号标识符if and only if 若且唯若当且仅当Illinois 伊利诺伊利诺斯image 影像图象immediate base 直接的(紧临的)上层 base class。
C++type_traits原理
C++type_traits原理⼀、简单介绍(1)、type_traits类型萃取,C++11中已经成为了⼀个核⼼模块。
(2)、标准库包括helper classes、type traits、type transformations三个模块。
(3)、type_traits是编译期就去确定具体的类型,从⽽根据不同的类型来执⾏不同的模块,消除重复,提⾼代码质量。
⼆、实现C++标准库中的type_traits使⽤⽅式这⾥不再介绍,我也在学习中,我这⾥根据⾃⼰的理解,来记录下type_traits的实现⽅式。
核⼼:模板(1)、理解模板template的⽤法。
(2)、理解模板template特化(全特化和偏特化)。
简单实现C++标准库的is_unsigned1 template <typename T>2struct isUnsigned3 {4static const bool value = false;5 };⾸先是⼀个⽀持所有类型模板isUnsigned, isUnsigned(unsigned)::value毫⽆疑问是flase;那如何使isUnsigned(unsigned)::value为true呢,那就需要增加⼀个unsigned的特化版本的isUnsignedtemplate <>struct isUnsigned<unsigned>{static const bool value = true;};此时,编译器在编译期间执⾏isUnsigned(unsigned)::value则会定位到此特化版本的模板类型。
测试代码1int main()2 {3 cout << isUnsigned<int>::value << endl;4 cout << isUnsigned<float>::value << endl;5 cout << isUnsigned<bool>::value << endl;6 cout << isUnsigned<unsigned>::value << endl;78return0;9 }测试结果。
两岸IT常术语对照表
两岸IT常用术语对照表以下是侯捷个人陆续收集整理的有关於我所涉猎的领域的术语对照(英中繁简)。
欢迎所有朋友给我意见(任何意见)。
谢谢。
新书写作,或发表文章时,我会以此表为叁考。
本表所列,并不表示我在写译书籍时一定会采用表内的中文术语。
我也可能采用英文术语。
一群性质相近同的「东西」,如果译名一贯,阅读的感觉就很好。
一贯性的术语,扩充性高,延伸性高,系统化高。
● 我喜欢「式」:constructor 建构式declaration 宣告式definition 定义式destructor 解构式expression 算式(运算式)function 函式pattern 范式、模式、样式program 程式signature 标记式(签名式/署名式)● 我喜欢「件」:(这是个弹性非常大的可组合字)assembly (装)配件component 组件construct 构件control 控件event 事件hardware 硬件object 物件part 零件、部件singleton 单件software 软件work 工件、机件● 我喜欢「器」:adapter 配接器allocator 配置器compiler 编译器container 容器iterator 迭代器linker 连结器listener 监听器interpreter 直译器translator 转译器/翻译器● 我喜欢「别」:class 类别type 型别● 我喜欢「化」:generalized 泛化specialized 特化overloaded 多载化(重载)● 我喜欢「型」:polymorphism 多型genericity 泛型● 我喜欢「程」:process 行程/进程(大陆用语)thread 绪程/线程(大陆用语)programming 编程●英中繁简编程术语对照英文繁体译词(有些是侯捷个人喜好,普及与否难说)大陆惯用术语---------------------------------------------------------------------------------------#define 定义预定义abstract 抽象的抽象的abstraction 抽象体、抽象物、抽象性抽象体、抽象物、抽象性access 存取、取用存取、访问access level 存取级别访问级别access function 存取函式访问函数activate 活化激活active 作用中的adapter 配接器适配器address 位址地址address space 位址空间,定址空间address-of operator 取址运算子取地址操作符aggregation 聚合algorithm 演算法算法allocate 配置分配allocator (空间)配置器分配器application 应用程式应用、应用程序application framework 应用程式框架、应用框架应用程序框架architecture 架构、系统架构体系结构argument 引数(传给函式的值)。
c++模板高级用法
c++模板高级用法C++模板的高级用法包括模板特化、模板偏特化、模板元编程和可变参数模板等。
1. 模板特化(Template Specialization):可以针对特定类型或特定条件对模板进行特殊处理。
特化可以分为部分特化和完全特化两种。
部分特化是在给定一组类型参数的情况下,对特定情况进行处理;完全特化是在给定特定类型参数的情况下,对特定类型进行处理。
示例:```cpptemplate <typename T>class MyClass {// 通用实现};template <>class MyClass<int> {// int类型特化实现};```2. 模板偏特化(Template Partial Specialization):特化模板的一种形式,可以针对特定类型或特定条件对模板进行特殊处理。
与完全特化不同的是,模板偏特化只针对某些类型或条件进行处理,而不是所有类型。
示例:```cpptemplate <typename T, typename U>class MyClass {// 通用实现};template <typename T>class MyClass<T, int> {// T为任意类型,U为int类型时的特化实现};```3. 模板元编程(Template Metaprogramming):利用模板的特殊机制实现在编译时进行运算和计算的技术。
模板元编程可以在编译时生成代码,执行编译期间的计算。
示例:```cpptemplate <int N>struct Factorial {enum { value = N * Factorial<N - 1>::value };};template <>struct Factorial<0> {enum { value = 1 };};int main() {int result = Factorial<5>::value; // 编译时计算5的阶乘return 0;}```4. 可变参数模板(Variadic Templates):允许模板接受任意数量的参数。
C++Primer学习笔记-模板特例化
C++Primer学习笔记-模板特例化⽬录模板特例化由来单⼀模板对任何可能的模板实参并总是合适,并且能实例化的。
⽐如,compare的例⼦,⽤于⽐较2个实参:// 第⼀个版本:⽐较任意两个类型template <typename T>int compare(const T&, const T&);// 第⼆个版本:可以⽐较字符串字⾯量template <size_t N, size_t M>int compare(const char (&)[N], const char (&)[N]);第⼀个版本compare可⽤于⽐较任意两个类型,第⼆个版本可以⽤于⽐较字符串字⾯量。
然⽽,当实参是2个字符串对应指针时,我们希望的是⽐较2个字符串⼤⼩,⽽第⼀个版本会直接⽐较2个指针⼤⼩,第⼆个版本⽆法将指针转化为⼀个数组的引⽤(因为编译器⽆法直接通过实参指针判断这是个什么类型)。
因此,这2个版本compare都是不⾏的。
为了解决这个字符指针的问题,我们引⼊模板特例化(template specialization)。
⼀个特例化版本就是模板的⼀个独⽴定义,其中⼀个或多个⽬标参数被指定为特定的类型。
另外,模板特例化在有的书籍简称“模板特化”。
定义函数模板特例化可以为第⼀个版本的compare定义⼀个模板特例化版本。
以template<>开头,“<>” 表⽰我们将为原模板的所有模板参数提供实参:// compare的特例化版本,⽤于处理字符串数组的指针的⽐较template<>int compare(const char* const &p1, const char* const &p2){return strcmp(p1, p2);}当我们定义⼀个特例化版本时,函数参数类型必须与先前声明的模板中对于的类型匹配。
java常用英语词汇翻译
abstract 抽象的抽象的abstraction 抽象体、抽象物、抽象性抽象体、抽象物、抽象性access 存取、取用存取、访问access level 存取级别访问级别access function 存取函式访问函数activate 活化激活active 作用中的adapter 配接器适配器address 位址地址address space 位址空间,定址空间address-of operator 取址运算子取地址操作符aggregation 聚合algorithm 演算法算法allocate 配置分配allocator (空间)配置器分配器application 应用程式应用、应用程序application framework 应用程式框架、应用框架应用程序框架architecture 架构、系统架构体系结构argument 引数(传给函式的值)。
叁见 parameter 叁数、实质叁数、实叁、自变量array 阵列数组arrow operator arrow(箭头)运算子箭头操作符assembly 装配件assembly language 组合语言汇编语言assert(ion) 断言assign 指派、指定、设值、赋值赋值assignment 指派、指定赋值、分配assignment operator 指派(赋值)运算子 = 赋值操作符associated 相应的、相关的相关的、关联、相应的associative container 关联式容器(对应 sequential container)关联式容器atomic 不可分割的原子的attribute 属性属性、特性audio 音讯音频A.I. 人工智慧人工智能background 背景背景(用於图形着色)後台(用於行程)backward compatible 回溯相容向下兼容bandwidth 频宽带宽base class 基础类别基类base type 基础型别 (等同於 base class)batch 批次(意思是整批作业)批处理benefit 利益收益best viable function 最佳可行函式最佳可行函式(从 viable functions 中挑出的最佳吻合者)binary search 二分搜寻法二分查找binary tree 二元树二叉树binary function 二元函式双叁函数binary operator 二元运算子二元操作符binding 系结绑定bit 位元位bit field 位元栏位域bitmap 位元图位图bitwise 以 bit 为单元逐一┅bitwise copy 以 bit 为单元进行复制;位元逐一复制位拷贝block 区块,区段块、区块、语句块boolean 布林值(真假值,true 或 false)布尔值border 边框、框线边框brace(curly brace) 大括弧、大括号花括弧、花括号bracket(square brakcet) 中括弧、中括号方括弧、方括号breakpoint 中断点断点build 建造、构筑、建置(MS 用语)build-in 内建内置bus 汇流排总线business 商务,业务业务buttons 按钮按钮byte 位元组(由 8 bits 组成)字节cache 快取高速缓存call 呼叫、叫用调用callback 回呼回调call operator call(函式呼叫)运算子调用操作符(同 function call operator)candidate function 候选函式候选函数(在函式多载决议程序中出现的候选函式)chain 串链(例 chain of function calls)链character 字元字符check box 核取方块 (i.e. check button) 复选框checked exception 可控式异常(Java)check button 方钮 (i.e. check box) 复选按钮child class 子类别(或称为derived class, subtype)子类class 类别类class body 类别本体类体class declaration 类别宣告、类别宣告式类声明class definition 类别定义、类别定义式类定义class derivation list 类别衍化列类继承列表class head 类别表头类头class hierarchy 类别继承体系, 类别阶层类层次体系class library 类别程式库、类别库类库class template 类别模板、类别范本类模板class template partial specializations类别模板偏特化类模板部分特化class template specializations类别模板特化类模板特化cleanup 清理、善後清理、清除client 客端、客户端、客户客户client-server 主从架构客户/服务器clipboard 剪贴簿剪贴板clone 复制克隆collection 群集集合combo box 复合方块、复合框组合框command line 命令列命令行(系统文字模式下的整行执行命令)communication 通讯通讯compatible 相容兼容compile time 编译期编译期、编译时compiler 编译器编译器component 组件组件composition 复合、合成、组合组合computer 电脑、计算机计算机、电脑concept 概念概念concrete 具象的实在的concurrent 并行并发configuration 组态配置connection 连接,连线(网络,资料库)连接constraint 约束(条件)construct 构件构件container 容器容器(存放资料的某种结构如 list, vector...)containment 内含包容context 背景关系、周遭环境、上下脉络环境、上下文control 控制元件、控件控件console 主控台控制台const 常数(constant 的缩写,C++ 关键字)constant 常数(相对於 variable)常量constructor(ctor)建构式构造函数(与class 同名的一种 member functions)copy (v) 复制、拷贝拷贝copy (n) 复件, 副本cover 涵盖覆盖create 创建、建立、产生、生成创建creation 产生、生成创建cursor 游标光标custom 订制、自定定制data 资料数据database 资料库数据库database schema 数据库结构纲目data member 资料成员、成员变数数据成员、成员变量data structure 资料结构数据结构datagram 资料元数据报文dead lock 死结死锁debug 除错调试debugger 除错器调试器declaration 宣告、宣告式声明deduction 推导(例:template argument deduction)推导、推断default 预设缺省、默认defer 延缓推迟define 定义预定义definition 定义、定义区、定义式定义delegate 委派、委托、委任委托delegation (同上)demarshal 反编列散集dereference 提领(取出指标所指物体的内容)解叁考dereference operator dereference(提领)运算子 * 解叁考操作符derived class 衍生类别派生类design by contract 契约式设计design pattern 设计范式、设计样式设计模式※最近我比较喜欢「设计范式」一词destroy 摧毁、销毁destructor 解构式析构函数device 装置、设备设备dialog 对话窗、对话盒对话框directive 指令(例:using directive) (编译)指示符directory 目录目录disk 碟盘dispatch 分派分派distributed computing 分布式计算 (分布式电算) 分布式计算分散式计算 (分散式电算)document 文件文档dot operator dot(句点)运算子 . (圆)点操作符driver 驱动程式驱动(程序)dynamic binding 动态系结动态绑定efficiency 效率效率efficient 高效高效end user 终端用户entity 物体实体、物体encapsulation 封装封装enclosing class 外围类别(与巢状类别 nested class 有关)外围类enum (enumeration) 列举(一种 C++ 资料型别)枚举enumerators 列举元(enum 型别中的成员)枚举成员、枚举器equal 相等相等equality 相等性相等性equality operator equality(等号)运算子 == 等号操作符equivalence 等价性、等同性、对等性等价性equivalent 等价、等同、对等等价escape code 转义码转义码evaluate 评估、求值、核定评估event 事件事件event driven 事件驱动的事件驱动的exception 异常情况异常exception declaration 异常宣告(ref. C++ Primer 3/e, 11.3)异常声明exception handling 异常处理、异常处理机制异常处理、异常处理机制exception specification 异常规格(ref. C++ Primer 3/e, 11.4)异常规范exit 退离(指离开函式时的那一个执行点)退出explicit 明白的、明显的、显式显式export 汇出引出、导出expression 运算式、算式表达式facility 设施、设备设施、设备feature 特性field 栏位,资料栏(Java)字段, 值域(Java)file 档案文件firmware 韧体固件flag 旗标标记flash memory 快闪记忆体闪存flexibility 弹性灵活性flush 清理、扫清刷新font 字型字体form 表单(programming 用语)窗体formal parameter 形式叁数形式叁数forward declaration 前置宣告前置声明forwarding 转呼叫,转发转发forwarding function 转呼叫函式,转发函式转发函数fractal 碎形分形framework 框架框架full specialization 全特化(ref. partial specialization)function 函式、函数函数function call operator 同 call operatorfunction object 函式物件(ref. C++ Primer 3/e, 12.3)函数对象function overloaded resolution函式多载决议程序函数重载解决(方案)functionality 功能、机能功能function template 函式模板、函式范本函数模板functor 仿函式仿函式、函子game 游戏游戏generate 生成generic 泛型、一般化的一般化的、通用的、泛化generic algorithm 泛型演算法通用算法getter (相对於 setter) 取值函式global 全域的(对应於 local)全局的global object 全域物件全局对象global scope resolution operator全域生存空间(范围决议)运算子 :: 全局范围解析操作符group 群组group box 群组方块分组框guard clause 卫述句 (Refactoring, p250) 卫语句GUI 图形介面图形界面hand shaking 握手协商handle 识别码、识别号、号码牌、权柄句柄handler 处理常式处理函数hard-coded 编死的硬编码的hard-copy 硬拷图屏幕截图hard disk 硬碟硬盘hardware 硬体硬件hash table 杂凑表哈希表、散列表header file 表头档、标头档头文件heap 堆积堆hierarchy 阶层体系层次结构(体系)hook 挂钩钩子hyperlink 超链结超链接icon 图示、图标图标IDE 整合开发环境集成开发环境identifier 识别字、识别符号标识符if and only if 若且唯若当且仅当Illinois 伊利诺伊利诺斯image 影像图象immediate base 直接的(紧临的)上层 base class。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
摘要:本文通过例子介绍了在C++标准库中广泛使用的模板特化和偏特化,并指出了模板特化和偏特化的定义规则和应用规则。
关键词:模板、特化、偏特化
1.引言
C++中的模板分为类模板和函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,这一点在STL中有着充分的体现。
目前,STL 在C++社区中得到了广泛的关注、应用和研究。
理解和掌握模板是学习、应用和研究以及扩充STL的基础。
而STL模板实例中又充斥着大量的模板特化和偏特化。
2.模板的定义
(1) 类模板
定义一个栈的类模板,它可以用来容纳不同的数据类型
说明如下:
template <class T>
class stack {
private:
list* top;
public:
stack();
stack(const stack&);
~stack();
void push(T&);
T& pop();
//…
};
上述定义中,template告诉编译器这是一个模板,尖括号中的<class T >指明模板的参数,可以有一个或多个,具体实现时由用户指定,其中template <class T >中的关键字class可以用关键字typename来代替。
类模板的使用除了要在声明时指明模板参数外,其余均与普通的类相同,例如:stack<int>int_stack;
stack<char>ch_stack;
stack<string>str_stack;
int_stack.push(10);
ch_stack.push(…z‟);
str_stack.push(“c++”);
(2)函数模板
假设现在要定义一个max函数来返回同一类型(这种类型是允许比较的)两个值的最大者.
template<class T>
T mymax(const T&t1,const T&t2)
{ return t1 <t2 ? t2 : t1; }
template <class T>的意义与类模板定义中相同。
模板函数的使用与普通非模板函数使用相同,因为模板函数的参数可以从其传入参数中解析出来。
例如:
int highest = mymax(5,10);
char c = mymax(…a‟, ‟z‟);
mymax(5,10)解析出模板函数参数为int, mymax(…a‟, ‟z‟)解析出模板函数的参数为char。
3.模板的特化
(1)类模板特化
有时为了需要,针对特定的类型,需要对模板进行特化,也就是特殊处理.例如,stack 类模板针对bool类型,因为实际上bool类型只需要一个二进制位,就可以对其进行存储,使用一个字或者一个字节都是浪费存储空间的.
template <class T>
class stack {};
template <>
class stack<bool>{ //…// };
上述定义中template <>告诉编译器这是一个特化的模板。
(2) 函数模板的特化
看下面的例子
main()
{
int highest = mymax(5,10);
char c = mymax(…a‟, ‟z‟);
const char* p1 = “hello”;
const char* p2 = “world”;
const char* p = mymax(p1,p2);
}
前面两个mymax都能返回正确的结果.而第三个却不能,因为,此时mymax直接比较两个指针p1 和p2 而不是其指向的内容.
针对这种情况,当mymax函数的参数类型为const char* 时,需要特化。
template <class T>
T mymax(const T t1, const T t2)
{
return t1 <t2 ? t2 : t1;
}
template <>
const char* mymax(const char* t1,const char* t2)
{
return (strcmp(t1,t2) <0) ? t2 : t1;
}
现在mymax(p1,p2)能够返回正确的结果了。
4.模板的偏特化
模板的偏特化是指需要根据模板的某些但不是全部的参数进行特化
(1) 类模板的偏特化
例如c++标准库中的类vector的定义
template <class T, class Allocator>
class vector { // … // };
template <class Allocator>
class vector<bool, Allocator>{ //…//};
这个偏特化的例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。
(2) 函数模板的偏特化
严格的来说,函数模板并不支持偏特化,但由于可以对函数进行重载,所以可以达到类似于类模板偏特化的效果。
template <class T>void f(T); (a)
根据重载规则,对(a)进行重载
template <class T>void f(T*); (b)
如果将(a)称为基模板,那么(b)称为对基模板(a)的重载,而非对(a)的偏特化。
C++的标准委员会仍在对下一个版本中是否允许函数模板的偏特化进行讨论。
5.模板特化时的匹配规则
(1) 类模板的匹配规则
最优化的优于次特化的,即模板参数最精确匹配的具有最高的优先权
例子:
template <class T>class vector{//…//}; // (a)普通型
template <class T>class vector<T*>{//…//};// (b) 对指针类型特化template <>class vector <void*>{//…//};// (c) 对void*进行特化
每个类型都可以用作普通型(a)的参数,但只有指针类型才能用作(b)的参数,而只有void*才能作为(c)的参数
(2) 函数模板的匹配规则
非模板函数具有最高的优先权。
如果不存在匹配的非模板函数的话,那么最匹配的和最特化的函数具有高优先权
例子:
template <class T>void f(T); // (d)
template <class T>void f(int, T, double); // (e)
template <class T>void f(T*); // (f)
template <>void f<int>(int) ; // (g)
void f(double); // (h)
bool b;
int i;
double d;
f(b); // 以T = bool 调用(d)
f(i,42,d) // 以T = int 调用(e)
f(&i) ; // 以T = int* 调用(f)
f(d); // 调用(g)
作者:谢宝陵周生
(合肥市炮兵学院计算中心230031)。