各类关键字
测试程序使用namespace
包裹
示例代码:
类模板
可以允许使用者任意指定的部分可以抽出成为模板
template<typename T>
// 使用的时候在指明类型
class complex
{
public:
complex (T r = 0. T i = 0) : re(r), im(i) {}
complex& operator += (const complex&);
T real() const {return re;}
T imag() const {return im;}
private:
T re, im;s
}
函数模板
语法和类模板一样
template<typename T>
inline
const T& min(const T& a, const T& b) {return b < a ? b : a;}
// 使用的时候不需要指名类型 -> <符号的本质是操作符重载
stone r1(2, 3), r2(3, 3);
r3 = min(r1, r2);
成员模板
模板里面的member
,该member
本身又是一个template
-> 模板内的模板 -> 主要用来设计构造函数
示例代码:
template<class T1, class T2>
struct pair
{
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1& a, const T2& b) : first(a), second(b) {}
// 再设计模板
template<class U1, class U2>
pair(const pair<U1, U2>& p) : first(p.first), second(p.second) { }
};
模板特化
专门针对某一类型设计的函数
示例代码:
partial specialization 模板偏特化(个数的偏特化,范围的偏特化)
个数偏特化:
template<typename T, typename Alloc=...>
class vector
{
}
T
是指定函数类型.Alloc
是指定函数的分配器(标准库的内容)
c++
当中最小单位是char
类型.八位,如果是bool
类型那么只占用一位.那么就不需要使用泛化
实际上就是在声明模板的时候指定一个模板的泛化值是什么(类似声明形参的时候赋予初始值)
示例代码:
template<typename Alloc=...>
class vertor<bool, Alloc>
{
}
范围上的偏特化
如果设计一个模板特化类型T
,但是他不是一个具体的类型.他是一个指针.指向任意类型.所以T
的范围就缩小了
示例代码:
template<typename T>
class C
{
}
在声明一个指针的T
template<typename U>
class C<U*>
{
}
如果使用者用的是指针,编译器会使用下面一套代码.如果是指针,那么编译器会用上面一套代码
T*
表示指向什么都可以
使用者声明方式:
c<string> obj1; // 使用上面一个T代码
c<string*> obj2; // 使用下面一个U*代码
template template parameter模板模板参数
声明一个模板.有两个参数.第二个参数也是一个模板
示例代码:
目的是为了让使用者可以指定使用容器来构造类
容器需要指定元素类型和分配器
上面的模板模板声明完成后具体使用:
// 错误使用方式
// XCls<string, list> mylst1; -> list传入就是第二个Contrainer,会拿前面的T当前元素类型
// 之所以这里可以这样使用,是因为元素有第二模板参数.只是有默认值.如果这样使用语法过不了
// list的特性接收两个参数
XCls<string, Lst> mylst;
上诉代码当中传入的list
并没有绑定任何参数,所以它仍然是一个模糊的东西.这样才可以把它称之为模板
无法通过的原因是:容器接收好几个参数
如果只接收一个参数那么是可以通过的
示例代码:
使用方式:
XCls<string, shared_ptr> p1;
// XCls<double, unique_ptr> p2; -> 由于unique_ptr的特性所以上述的声明方式进行这样构造是不可以的
非模板模板偏特化:
template<class T, class Sequence = deque<T>>
class stack {
friend bool operator== <> (const stack&, const stack&);
friend bool operator< <> (const stack&, const stack&);
protected:
Sequence c; // 底层容器
};
在这段代码当中,由于Sequence
有默认初始值.所以在声明调用的时候有两种方式:
stack<int> s1;
stack<int, list<int>> s2;
在这个当中如果要修改第二个初始值.需要指定list<int>
并且向list
当中传入参数.那么它就不是一个模糊的值.而是一个被定义的值.所以不能视为模板
小结
It's a lonely road!!!
分类:
C_Cpp
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构