1. 算法容器的使用:

#include <iostream>
#include <functional>
#include <vector>
#include <algorithm> //算法,共包含108个算法
#include <numeric> //整数 using namespace std;
using namespace std::placeholders; //用于bind()函数的"_1"参数 struct MyStruct
{
int operator()(int data) //对()进行重载-->伪函数
{
return data % == ;
}
}; int get(int data)
{
return data % == ;
} struct my
{
int get(int data)
{
return data % == ;
}
}; int main()
{
vector<int> myint{ ,,,,,,,,, }; //创建容器
//法一:lambda表达式
int num1 = count_if(myint.begin(), myint.end(), [](int data)->bool {return data % == ; }); //偶数个数
//法二:伪函数(匿名对象)
int num2 = count_if(myint.begin(), myint.end(), MyStruct()); //MyStruct()匿名对象
//法三:有名对象
MyStruct my1;
int num3 = count_if(myint.begin(), myint.end(), my1);
//法四:函数
int num4 = count_if(myint.begin(), myint.end(), get);
//法五:成员函数(函数绑定器)
my my2;
auto fun = bind(&my::get, &my2, _1);
int num5 = count_if(myint.begin(), myint.end(), fun); cout << num1 << endl; //
cout << num2 << endl; //
cout << num3 << endl; //
cout << num4 << endl; //
cout << num5 << endl; // system("pause");
return ;
}

    

  1.1 加入函数模板如下:

#include <iostream>
#include <functional>
#include <vector>
#include <algorithm> //算法,共包含108个算法
#include <numeric> //整数 using namespace std;
using namespace std::placeholders; //用于bind()函数的"_1"参数 template<class T>
bool getT(T data)
{
return data % == ;
} int main()
{
vector<int> myint{ ,,,,,,,,, }; //创建容器 int num6 = count_if(myint.begin(), myint.end(), getT<int>);
cout << num6 << endl; // system("pause");
return ;
}

    

2. 模板的展开 ==> 属于模板元的范畴

#include <iostream>
#include <cstdarg>
using namespace std; template<class T>
void show(T t)
{
cout << t << " ";
} template<class...Args>
void all(Args...args)
{
int arr[] = { (show(args),)... }; //使用数组进行展开
} template<class...Args>
void allIt(Args...args)
{
int arr[] = { (show(args),)... }; //int arr[],用来约束展开多少层,保存在数组里面,[]不能省
} int main()
{
all(, , , , );
cout << endl;
all(, , , , , , , );
cout << endl;
allIt(, 'A', "", 7.89);
cout << endl; system("pause");
return ;
}

    

3. 函数模板推理机制:

#include <iostream>
using namespace std; template<typename T>
void go(T t) //将类型泛型
{
cout << typeid(T).name() << endl;
//cout << t << endl;
cout << "T:" << endl;
} template<int i> //模板之间也可以重载
void go() //数据可以为任意数据(相当于数字模板)
{
cout << i << endl;
} template<typename T>
void go(T *t) //将类型泛型
{
cout << typeid(T).name() << endl;
cout << "T *:" << t << endl;
} int main()
{
/*
go(31 - 2); //调用泛型函数模板 go<31 - 2>(); //调用数字模板 go<decltype(10 + 2)>(1234); //调用泛型函数模板,可以用decltype获取数据类型
*/ go(nullptr); //nullptr不是指针类型,是一种自定义的数据类型表示空指针而已,调用go(T t) int *p = nullptr; //调用go(T *t)
go(p); system("pause");
return ;
}

    

4. 函数指针与函数模板:

  4.1 函数模板赋值给函数指针:

#include <iostream>
using namespace std; template<class T>
void show(T t)
{
cout << t << endl;
} struct MyStruct
{
template<class T>
void show(T t)
{
cout << t << endl;
} void go()
{
show();
}
}; //函数模板赋值给函数指针
int main()
{
//void(*p)() = show<int>; //无法从“void (__cdecl *)(T)”转换为“void (__cdecl *)(void)”
void(*p1)(int i) = show<int>;
void(*p2)(double db) = show<double>; system("pause");
return ;
}

  4.2 如何调用结构体中的函数模板?

//如何调用结构体中的函数模板?
int main()
{
MyStruct my1;
my1.go(); //结构体内部调用结构体中的函数模板 my1.show(12.3); //外部直接调用结构体中的函数模板
my1.show('A');
my1.show<int>('A'); system("pause");
return ;
}

    

  4.3 如何绑定结构体内部的函数模板?

#include <iostream>
#include <functional> using namespace std;
using namespace std::placeholders; template<class T>
void show(T t)
{
cout << t << endl;
} struct MyStruct
{
template<class T>
void show(T t)
{
cout << t << endl;
} template<class T>
void showit(T t1, T t2)
{
cout << t1 << " " << t2 << endl;
} void go()
{
show();
}
}; //如何绑定结构体内部的函数模板?
int main()
{
MyStruct my1;
auto fun = bind(&MyStruct::showit<int>, &my1, , );
fun(); system("pause");
return ;
}

    

5. 函数模板、模板函数与类模板:

  5.1 什么是函数模板?什么是模板函数?

    函数模板就是上面所讲的函数模板,而模板函数则是实例化的函数模板

#include <iostream>
using namespace std; /*函数模板,不调用不编译*/
template<class T>
T add(T a, T b)
{
return a + b;
} int main()
{
add(, ); /*模板函数,也就是实例化的函数模板,自动根据参数推理*/
add<double>(, 1.2); /*模板函数*/ system("pause");
return ;
}

  5.2 类成员函数模板:

#include <iostream>
using namespace std; class myclass
{
public:
template<class T> //类成员函数模板
T add(T a, T b)
{
return a + b;
} template<class T> //静态函数模板
static T sub(T a, T b)
{
return a - b;
}
}; int main()
{
myclass *p = nullptr;
int num1 = p->add<int>(, ); //强行指定的模板函数,当做类成员函数调用
int num2 = p->add(, ); //自动推理的模板函数
cout << num1 << endl;
cout << num2 << endl; int num3 = myclass::sub( , );
cout << num3 << endl; system("pause");
return ;
}

    

6. 模板在类中的应用:

#include <iostream>
#include <cstdlib>
using namespace std; class myclass
{
public:
template<class T>
T add(T a)
{
return a;
} template<class T>
T add(T a,T b)
{
show(); //函数模板与类成员函数可以互相调用
return a + b;
} template<class T>
T add(T a, T b,T c)
{
return a + b + c;
} //template<class T>
//virtual T add(T a, T b,T c) //error C2898: “T myclass::add(T,T,T)”: 成员函数模板不能是虚拟的
//{
// return a + b + c;
//} void show()
{
cout << add<int>() << endl; //指明类型的方式调用
} }; int main()
{
myclass *p = nullptr;
p->add(, ); system("pause");
return ;
}

7. 类模板与函数模板对比:

#include <iostream>
#include <initializer_list>
#include <memory>
#include <string>
using namespace std; template<class T,int n>
class myarray
{
T *p;
public:
myarray(initializer_list<T> mylist)
{
p = new T[n]; //开辟内存
memset(p, , sizeof(T)*n); //内存清0 int length = mylist.size();
if (length > n)
{
abort(); //触发异常
}
else
{
int i = ;
for (auto j : mylist) //数据填充
{
p[i] = j;
i++;
}
}
} ~myarray()
{
delete[] p;
} void show() //显示数据
{
for (int i = ; i < n; i++)
{
cout << p[i] << " ";
}
cout << endl;
} void sort() //冒泡排序
{
for (int i = ; i < n - ; i++)
{
for (int j = ; j < n - - i; j++)
{
if (p[j] < p[j+]) //从大到小
{
T temp = p[j];
p[j] = p[j + ];
p[j + ] = temp;
}
}
}
}
}; int main()
{
myarray<int, > my1 = { ,,,,,,,, };
my1.show();
my1.sort();
my1.show(); myarray<double, > my2 = { 1.1,2.2,3.3,4.4,5.5 };
my2.show();
my2.sort();
my2.show(); myarray<string, > my3 = { "","abcdef","sdaf","hello" };
my3.show();
my3.sort();
my3.show(); system("pause");
return ;
}

    

8. 类包装器:

#include <iostream>
using namespace std; template<class T,class F> //函数模板
T run(T t, F f)
{
return f(t);
} class fun
{
public:
double operator ()(double data)
{
return data - ;
} }; template<class T> //类模板
class Tfun
{
public:
T operator ()(T data)
{
return data - ;
} }; int main()
{
cout << run(10.9, fun()) << endl; //fun()是匿名对象
fun x;
cout << run(10.9, x) << endl; //x是有名对象 cout << run(10.9, Tfun<double>()) << endl; //模板函数的匿名对象,构造函数返回的就是匿名对象
Tfun<double> fang;
cout << run(10.9, fang) << endl; system("pause");
return ;
}

    

9. 高级类包装器:

#include <iostream>
#include <list>
#include <vector>
using namespace std; template<class T, class F> //函数模板
T run(T t, F f)
{
return f(t);
} template<class T> //类模板
class Trun
{
public:
T operator ()(T data)
{
for (auto i:data)
{
cout << i <<" ";
}
cout << endl;
return data;
} }; int main()
{
list<int> myint; //构建链表,压入数据
for (int i = ; i < ; i++)
{
myint.push_back(i);
} run(myint, //lambda表达式
[](list<int> myint)->list<int>
{
for (auto i : myint)
{
cout << i << endl;
}
return myint;
}
); system("pause");
return ;
}

    

#include <iostream>
#include <list>
#include <vector>
using namespace std; template<class T, class F> //函数模板
T run(T t, F f)
{
return f(t);
} template<class T> //类模板
class Trun
{
public:
T operator ()(T data)
{
for (auto i:data)
{
cout << i <<" ";
}
cout << endl;
return data;
} }; int main()
{
vector<int> myv{ ,,,,,, };
run(myv, Trun< vector<int> >()); //匿名对象,用完就扔
run(myv, Trun< decltype(myv) >()); system("pause");
return ;
}

    

 10. 类模板间的封装、继承、多态:

  10.1 父类为类模板,子类也是类模板:

#include <iostream>
using namespace std; //类模板支持封装、继承、多态
template<class T>
class Tfu
{
public:
T t;
Tfu():t()
{
} void show()
{
cout << t << endl;
} virtual void go()
{
cout << "fu:" << t << endl;
}
}; template<class T>
class Tzi :public Tfu<T>
{
public:
void go()
{
cout << "zi:" << t << endl;
}
}; int main()
{
Tzi<int> tzi;
tzi.t = ;
tzi.show(); Tfu<int> *p = new Tzi<int>; //实现多态
p->go(); system("pause");
return ;
}

    

  10.2 父类为类模板,子类为普通类:

#include <iostream>
using namespace std; template<class T>
class Tfu
{
public:
T t;
Tfu() :t()
{
} void show()
{
cout << t << endl;
} virtual void go()
{
cout << "fu:" << t << endl;
}
}; class zi :public Tfu<int>
{
public:
void go()
{
cout << "zi:" << t << endl;
}
}; int main()
{
zi z1;
z1.t = ;
z1.show(); Tfu<int> *p = new zi; //多态 此处只能用int
p->go(); system("pause");
return ;
}

    

  10.3  父类为普通类,子类为类模板:

#include <iostream>
using namespace std; //类模板支持封装、继承、多态 //T T //类模板 可以实现封装、继承、多态
//T P //类模板与类 可以实现封装、继承、多态 必须明确类型
//P T //类与类模板 可以实现封装、继承、多态 必须明确类型 多态什么类型都可以
//P P //普通类 可以实现封装、继承、多态
class die
{
public:
int t;
die() :t()
{
} void show()
{
cout << t << endl;
} virtual void go()
{
cout << "fu: " << t << endl;
}
}; template<class T>
class er :public die
{
public:
void go()
{
cout << typeid(T).name() << " zi: " << t << endl;
} }; int main()
{
er<double> boer;
boer.show(); die *p1 = new er<char>;
die *p2 = new er<int>;
die *p3 = new er<double>;
p1->go();
p2->go();
p3->go(); system("pause");
return ;
}

    

3. STL编程三的更多相关文章

  1. C++ STL编程轻松入门基础

    C++ STL编程轻松入门基础 1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL 1.2 追根溯源:STL的历史 1.3 千丝万缕的联系 1.4 STL的不同实现版本 2 牛刀小试 ...

  2. Linux网络编程(三)

    Linux网络编程(三) wait()还是waitpid() Linux网络编程(二)存在客户端断开连接后,服务器端存在大量僵尸进程.这是由于服务器子进程终止后,发送SIGCHLD信号给父进程,而父进 ...

  3. Java并发编程三个性质:原子性、可见性、有序性

      并发编程 并发程序要正确地执行,必须要保证其具备原子性.可见性以及有序性:只要有一个没有被保证,就有可能会导致程序运行不正确  线程不安全在编译.测试甚至上线使用时,并不一定能发现,因为受到当时的 ...

  4. 【读书笔记】.Net并行编程(三)---并行集合

    为了让共享的数组,集合能够被多线程更新,我们现在(.net4.0之后)可以使用并发集合来实现这个功能.而System.Collections和System.Collections.Generic命名空 ...

  5. 【憩园】C#并发编程之异步编程(三)

      写在前面 本篇是异步编程系列的第三篇,本来计划第三篇的内容是介绍异步编程中常用的几个方法,但是前两篇写出来后,身边的朋友总是会有其他问题,所以决定再续写一篇,作为异步编程(一)和异步编程(二)的补 ...

  6. C++ STL编程轻松入门【转载】

    1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL "什么是STL?",假如你对STL还知之甚少,那么我想,你一定很想知道这个问题的答案,坦率地讲,要指望用短短数 ...

  7. C++面向对象高级编程(三)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 一.拷贝构造 二.拷贝赋值 三.重写操作符 四.生命周期 本节主要介绍 Big Three 即析构函数,拷贝构造函数,赋值拷贝函数,前面主 ...

  8. OpenGL ES2.0编程三步曲 -转

    原地址:http://blog.csdn.net/myarrow/article/details/7707943 1. 保存全局变量的数据结构 以下例子程序均基于Linux平台. typedef st ...

  9. STL编程:C++的忠告!

    Copy别人的,有少量修改,可以做为一下参考! C++之父Bjarne Stroustrup 写的 The C++ Programming Language (Special Edition) 中各章 ...

随机推荐

  1. CHEMISTS DISCOVER A SAFE, GREEN METHOD TO PROCESS RED PHOSPHORUS

                   When it comes to making phosphorus compounds, chemists have traditionally relied on w ...

  2. Leetcode:Add Two Numbers分析和实现

    Add Two Numbers这个问题的意思是,提供两条链表,每条链表表示一个十进制整数,其每一位对应链表的一个结点.比如345表示为链表5->4->3.而我们需要做的就是将两条链表代表的 ...

  3. PHP与Imagemagick

    Imagemagick:相关站点: ImageMagick中文站:http://www.imagemagick.com.cn/ ImageMagick英文站:http://www.imagemagic ...

  4. kafka常用运维命令

    列出所有topic:bin/kafka-topics.sh --zookeeper localhost:2181 --list说明:其实就是去检查zk上节点的/brokers/topics子节点,打印 ...

  5. 21-py3 发邮件

    Python3 SMTP发送邮件 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. p ...

  6. 10 Examples of HotSpot JVM Options in Java[z]

    There are hundreds of JVM parameters or JVM Options exists inside sun JDK and its virtually impossib ...

  7. Java Thread系列(二)线程状态

    Java Thread系列(二)线程状态 一.线程的五种状态 新建状态(New):新创建了一个线程对象,尚未启动. 就绪状态(Runnable):也叫可运行状态.线程对象创建后,其他线程调用了该对象的 ...

  8. Linux下删除文件系统空间不释放的问题

    删除了Linux下的一个文件,但是系统空间并没有被释放. 如下:/home/hadmin/data/hadoop 使用了1.3T的空间,但是实际只使用了600多G 原因是我删除了一个600多G的文件, ...

  9. SpringCloud之自动化配置-config

    编程开发的时候有没有觉得很多配置文件需要维护,比如,修改了数据库连接,所有用到该数据库的服务配置都得替换,是不是超级的麻烦呢 下面,给大家介绍一下Spring提供的配置自动化组件-spring clo ...

  10. 【工具推荐】ELMAH——可插拔错误日志工具(转)

    出处:http://www.cnblogs.com/liping13599168/archive/2011/02/23/1962625.html 今天看到一篇文章(构建ASP.NET网站十大必备工具( ...