c++模板笔记

使用vc2015
进行C++ 模板的学习实验和笔记 用简单示例学习了解STL

template大部头理论书 讲解各种规则和各种规则例外的解决办法 集中精力在20%的规则中的阴暗角落而不是80%实践中要注意的东西

https://github.com/wuye9036/CppTemplateTutorial
这个模板教程是强烈推荐 易懂 看完可用于个人的一些代码中进行模板编程 实用

第一个示例
//=============================================
int add(int a ,int b)
{
return a+b;
}

int main()
{
add(3,8);
add(7,12);
return 0;
}
//============================================
如果说
函数是变量之间的操作方式复用方案
比如 3+8 7+12 都是调用add函数
那么模板就是变量的类型的复用方案
比如

#include <iostream>
template<typename T>
const T& compare(T& a, T& b)
{
return a > b? a :b;
}

int main()
{
int a = 7, b = 8, c = 9, d = 3;
std::cout << compare<int>(a, b) << std::endl;
std::cout << compare(c, d) << std::endl;
char f = ‘f‘, g = ‘z‘;
std::cout << compare(f, g) << std::endl;
return 0;
}

compare这个模板函数对于变量的比较方式都是一致的 ,就是比较两个变量的大小
而且对于 int 和 char 两种变量类型的比较都适用
就是我所说的对于变量的类型的复用方案
由于模板T对应的变量类型在本例中可以从函数参数推导得出 所以<int>这个符号并不强制需要写出来。

下面示例是一个链表 链表中每个节点可以存储不同类型元素
#include <iostream>
#include <string>

template<typename TYPE,typename NEXT>
struct AnyList {
TYPE value;
NEXT* next;
AnyList(TYPE const &v,NEXT *n):value(v),next(n){}
};

int main()
{
typedef AnyList<int, void> node_0;
node_0 zero(4,NULL) ;
typedef AnyList<char, node_0> node_1;
node_1 one(‘z‘,&zero);
typedef AnyList<std::string, node_1> node_2;
node_2 two("test", &one);

std::cout << two.value << std::endl;
std::cout << one.value << std::endl;
std::cout << zero.value << std::endl;

std::cout << two.value << std::endl;
std::cout << two.next->value << std::endl;
std::cout << two.next->next->value << std::endl;

return 0;
}

示意图:略

STL中FOREACH示例学习(函数指针模板参数)
#include <iostream>
#include <string>

template<typename T,void(*f)(T &v)>
void foreach(T array[], unsigned size)
{
for (unsigned i = 0; i < size; ++i)
f(array[i]);
}

template<typename T>
void inc(T& v) { ++v; }

template<typename T>
void dec(T& v) { --v; }

template<typename T>
void print(T& v) { std::cout << ‘ ‘ << v << std::endl; }

int main()
{
int array[] = { 1,2,3,4,5,6,7,8 };

foreach<int, print<int>>(array, 8);
std::cout << std::endl;

foreach<int, inc<int>>(array, 8);
foreach<int, print<int>>(array, 8);
std::cout << std::endl;

foreach<int, dec<int>>(array, 8);
foreach<int, print<int>>(array, 8);
std::cout << std::endl;

return 0;
}
FOREACH函数从模板接收操作类型和操作函数,从参数中接收要操作的数组和数组长度
//===============================================
指针与引用模板参数

#include <iostream>
#include <string>

template<typename T>
class wrapper;

template<typename T>
class wrapper<T*> {
public:
T* p;
wrapper(T* t):p(t){}
T get() { return *p; }
void set(T v) { *p = v; }
};

template<typename T>
class wrapper<T&> {
public:
T& p;
wrapper(T& t) :p(t) {}
T get() { return p; }
void set(T v) { p = v; }
};

int global_variable_int = 0;

char global_variable_char = ‘Z‘;

std::string global_variable_str = "this is a test";

int main()
{

wrapper<int*> gwrapper1(&global_variable_int);
gwrapper1.set(1);
std::cout << gwrapper1.get() << std::endl;

wrapper<int&> gwrapper2(global_variable_int);
gwrapper2.set(2);
std::cout << gwrapper2.get() << std::endl;

wrapper<char*> gwrapper3(&global_variable_char);
gwrapper3.set(‘a‘);
std::cout << gwrapper3.get() << std::endl;

wrapper<char&> gwrapper4(global_variable_char);
gwrapper4.set(‘g‘);
std::cout << gwrapper4.get() << std::endl;

wrapper<std::string*> gwrapper5(&global_variable_str);
std::cout << gwrapper5.get() << std::endl;

wrapper<std::string&> gwrapper6(global_variable_str);
gwrapper6.set("finish test");
std::cout << gwrapper6.get() << std::endl;

return 0;
}

根据参数的不同 自动选择不同的模板函数 指针或者引用
//======================================
模板的模板参数
如果模板中的模板不参与推导 可以省略不写
#include <iostream>
#include <string>

//template<template<typename TT> class Func, typename T>
template<template<typename> class Func, typename T>
void foreach(T array[], unsigned size)
{

Func<T> func;
for (unsigned i = 0; i < size; ++i)
func(array[i]);
}

template<typename T>
struct inc {
void operator()(T& v) { ++v; }
};

int main()
{
int arr[] = { 1,2,3,4,5 };
foreach<inc>(arr,5);
return 0;
}

时间: 2024-08-30 14:17:22

c++模板笔记的相关文章

&lt;模板&gt;笔记

<Absolute C++> chapter 16  ♦函数模板的函数定义和函数声明都是由如下代码开始的 template <class Type_Parameter> ♦之后便是函数的定义和函数体的定义,举例如下: template<class T> void swapValues(T& var1, T& var2) {       T temp;       temp = var1;       var1 = var2;       var2 = t

Matrix Admin 后台模板笔记

一个后台模板用久了就想换一个.上次找到了Matrix Admin.和ACE一样都是Bootstrap风格,比较容易上手.Matrix要更健壮些.感觉拿去做用户界面也是可以的. 整体风格: 1.表单验证 验证是借助于jquery.validate.js . 有丰富的验证方法,更多API请戳这里 js: $("#basic_validate").validate({ rules:{ required:{ required:true }, email:{ required:true, ema

C++类模板笔记

今天在写一个链表类模板,然后我和平时写类一样,将头文件.h和.cpp分开写,然后编译器一直提示 类函数全是无法解析的外部命令,后面经查找资料,原来是因为: 模板定义很特殊. 由template<-> 处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知.在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义.所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义.

C++ Primer 学习笔记_14_标准模板库_bitset位集合容器

C++ Primer 学习笔记_14_标准模板库_bitset位集合容器 bitset容器是一个bit位元素的序列容器,每个元素只占一个bit位,取值为0或1,因而很节省内存空间.下图是一个bitset的存储示意图,它的10个元素只使用了两个字节的空间. 使用bitset需要声明头文件"#include <bitset>" 1.创建bitset对象 创建bitset对象时,必须要指定容器的大小.bitset对象的大小一经定义,就不能修改了.下面这条语句就定义了bitset对

C++ Primer 学习笔记_23_标准模板库_stack.

C++ Primer 学习笔记_11_标准模板库_stack.queue队列容器与priority_queue优先队列容器 1.stack堆栈 stack堆栈是一个后进先出(Last In First Out,LIFO)的线性表,插入和删除元素都只能在表的一端进行.插入元素的一端称为栈顶,而另一端称为栈底.插入元素叫入栈(Push),删除元素叫出栈(Pop).下图是堆栈示意图 堆栈只提供入栈,出栈,栈顶元素访问和判断是否为空等几种方法.采用push()方法将元素入栈:采用pop()方法出栈:采用

C++ Primer 学习笔记_77_模板与泛型编程 --实例化

模板与泛型编程 --实例化 引言: 模板是一个蓝图,它本身不是类或函数.编译器使用模板产生指定的类或函数的特定版本号.产生模板的特定类型实例的过程称为实例化. 模板在使用时将进行实例化,类模板在引用实际模板类型时实例化,函数模板在调用它或用它对函数指针进行初始化或赋值时实例化. 1.类的实例化 当编写Queue<int>qi时,编译器自己主动创建名为Queue<int>的类.实际上,编译器通过又一次编写Queue模板,用类型int取代模板形參的每次出现而创建Queue<int

C++ Primer 学习笔记_81_模板与泛型编程 --类模板成员[续1]

模板与泛型编程 --类模板成员[续1] 二.非类型形参的模板实参 template <int hi,int wid> class Screen { public: Screen():screen(hi * wid,'#'), cursor(hi * wid),height(hi),width(wid) {} //.. private: std::string screen; std::string::size_type cursor; std::string::size_type height

C++ Primer 学习笔记_82_模板与泛型编程 --类模板成员[续2]

模板与泛型编程 --类模板成员[续2] 六.完整的Queue类 Queue的完整定义: template <typename Type> class Queue; template <typename Type> ostream &operator<<(ostream &,const Queue<Type> &); template <typename Type> class QueueItem { friend clas

C++学习笔记47:链表的概念与结点类模板

学堂在线学习笔记 链表的概念与结点类模板 顺序访问的线性群体--链表类 链表是一种动态数据结构,可以用来表示顺序访问的线性群体: 链表是由系列结点组成,结点可以在运行时动态生成: 每一个结点包括数据域和指向链表中下一个结点的指针(即下一个结点的地址).如链表中每个结点中只有一个指向后继结点的指针,则该链表称为单链表: 单链表的结点类模板 template <class T> void Node<T>::insertAfter(Node<T> *p) { //p结点指针域