C++ Template 编程,泛型编程练习
#include <iostream>
#include <string>
#include <deque>
#include <stdexcept>
template <typename T>
class my_stack
{
private:
std::deque<T> elems;
public:
void push(T const &);
void pop();
T top()const;
bool empty()const{return elems.empty();}
//operator =
template <typename T2>
my_stack<T> & operator=(my_stack<T2> const&);
}; template <typename T>
void my_stack<T>::push(T const &elem)
{
elems.push_back(elem);
} template <typename T>
void my_stack<T>::pop()
{
if (this->empty())
{
throw std::out_of_range("the list is empty,please insert the elems\n");
}
elems.pop_back();
}
template <typename T>
T my_stack<T>::top()const
{
if(this->empty())
{
throw std::out_of_range("No elements\n"); }
return elems.back();
}
template <typename T>
template <typename T2>
my_stack<T>& my_stack<T>::operator=(my_stack<T2> const&op2)
{
if( (void*)this == (void *)&op2)
{
return *this;
}
my_stack<T2> tmp(op2); //copy constructor
elems.clear();
while(!tmp.empty())
{
elems.push_front(tmp.top()); //put in the front !...
tmp,pop(); // while loop breakdown
}
return *this;
} int main()
{
my_stack <int> int_stack;
my_stack <float> float_stack; float_stack = int_stack; return ;
}
<2> 模板作为模板的参数:
//
// Created by Administrator on 2017/5/7.
// #ifndef TASARG_TEMPPARM_H
#define TASARG_TEMPPARM_H #include <iostream>
///Value handle define here
template <typename T>
class GLY_handle
{
public:
GLY_handle();
T getValue() const ;
void setValue( T data) ; private:
T mValue;
}; template <typename T>
GLY_handle<T>::GLY_handle()
{
}
template <typename T>
T GLY_handle<T>::getValue() const {
return mValue;
}
template <typename T>
void GLY_handle<T>::setValue(T data) {
mValue = data;
} /// ----------------------GLY MAP----------------------------------------------
/// Ting is template class can handle value
template <template <typename T> class Ting,typename KeyT,typename ValueT>
class GLY_Map
{
public:
/// default
GLY_Map(); /// copy function
GLY_Map(const GLY_Map<Ting,KeyT,ValueT>&); /// getMethod
KeyT first() const;
ValueT second() const;
/// setMethod
void setMapValue(KeyT key,ValueT data); /// dataHandle
Ting<KeyT> &firstHandle() ;
Ting<ValueT> &secondHandle(); private:
Ting <KeyT> mKey;
Ting <ValueT> mValue;
}; template <template <typename T> class Ting,typename KeyT,typename ValueT>
GLY_Map<Ting,KeyT,ValueT>::GLY_Map()
{ }
/// GLY_MAP copy function define here
template <template <typename T> class Ting,typename KeyT,typename ValueT>
GLY_Map<Ting,KeyT,ValueT>::GLY_Map(const GLY_Map<Ting, KeyT, ValueT> & rhs)
{
// copy function
mKey = rhs.mKey;
mValue = rhs.mValue;
} template <template <typename T> class Ting,typename KeyT,typename ValueT>
KeyT GLY_Map<Ting,KeyT,ValueT>::first() const
{
return mKey.getValue();
} template <template <typename T> class Ting,typename KeyT,typename ValueT>
ValueT GLY_Map<Ting,KeyT,ValueT>::second() const
{
return mValue.getValue();
}
template <template <typename T> class Ting,typename KeyT,typename ValueT>
void GLY_Map<Ting,KeyT,ValueT>::setMapValue(KeyT key, ValueT data)
{
mKey.setValue(key);
mValue.setValue(data);
}
template <template <typename T> class Ting,typename KeyT,typename ValueT>
Ting<KeyT> & GLY_Map<Ting,KeyT,ValueT>::firstHandle()
{
return mKey;
}
template <template <typename T> class Ting,typename KeyT,typename ValueT>
Ting<ValueT> &GLY_Map<Ting,KeyT,ValueT>::secondHandle()
{
return mValue;
}
// Operator for std::cout
template <template <typename T> class Ting,typename KeyT,typename ValueT>
std::ostream &operator<<(std::ostream &os ,const GLY_Map<Ting,KeyT,ValueT> &data)
{
os << "Data key " <<data.first() <<"," << data.second();
return os;
}; #endif //TASARG_TEMPPARM_H
tempparm.h
#include <iostream>
#include "tempparm.h"
#include <vector> int main()
{
GLY_Map <GLY_handle,std::string,int> testMap;
testMap.setMapValue("houdini",);
std::cout << testMap <<std::endl;
return ;
}
main.cpp
<3> 默认模板参数:
template<class T1,class T2 = int>
class Topo{...}
Topo<double,double> T2 //as double
Topo<double>T2 //as int
<4> 显示具体化模板:
#include <iostream>
template <typename T>
class GLY_Handle
{
public:
T var;
void printData()
{
std::cout << "print as generic type " << var <<std::endl;
}
}; /// explicit the int type
template <>
class GLY_Handle<int>
{
public:
void printData()
{
std::cout << "print as int type " << var <<std::endl;
}
int var;
}; template <>
class GLY_Handle<float>
{
public:
void printData()
{
std::cout << "print as float type " <<var <<std::endl;
}
float var;
}; int main()
{
GLY_Handle<int> var1;
var1.var = ;
var1.printData(); GLY_Handle<double> var2;
var2.var = 10.0;
var2.printData(); GLY_Handle<float> var3;
var3.var = 10.0f;
var3.printData();
return ;
}
<5> 部分具体化模板:
<6>模板和友元函数,以及静态成员分配:
#include <iostream>
template <typename T>
class HasFriend
{
public:
HasFriend(const T & i):item(i) { ct++; }
~HasFriend() { ct--; }
friend void counts();
friend void reports(HasFriend<T> &);
private:
T item;
static int ct;
};
/// each specialization has its own static data member
template <typename T>
int HasFriend<T>::ct = ;
void counts()
{
std::cout << "int count " << HasFriend<int>::ct <<std::endl;
std::cout << "double count " <<HasFriend<double>::ct <<std::endl;
}
/// non-template friend to HasFriend<int> class
void reports(HasFriend <int> &pt) {
// 为什么能访问pt的私有函数,因为reports函数是在public接口上。
std::cout << "HasFriend<int>: " <<pt.item <<std::endl;
}
/// non-template friend to HasFriend<double> class
void reports(HasFriend <double> &pt) {
// 为什么能访问pt的私有函数,因为reports函数是在public接口上。
std::cout << "HasFriend<double>: " <<pt.item <<std::endl;
}
int main()
{
counts();
HasFriend<int> i_01();
HasFriend<int> i_02();
HasFriend<double> d_03(10.00); std::cout << "After i_01,i_02,d_03 declared\n\n";
counts(); reports(i_01);
reports(i_02);
reports(d_03); return ;
}
./out
int count 0
double count 0
After i_01,i_02,d_03 declared
int count 2
double count 1
HasFriend<int>: 1
HasFriend<int>: 10
HasFriend<double>: 10
<7>重载函数模版问题:
#include <iostream>
template <typename T>
int func(T) // first
{
return ;
} template <typename T>
int func(T*) //
{
return ;
} int main()
{
std::cout << func() <<std::endl; //
std::cout << func<int>() <<std::endl; //
std::cout << func((int*)) <<std::endl; // 2,T=int ,arg is int* // will create this function func<int*>(int*),
// and will create func<int*>(int**),because the second template function
// but (int*)5 is int* , so will match func<int*>((int*)) better
std::cout << func<int*>((int*)) <<std::endl; //-> func<int*>(int*) std::cout << func<int> ((int*)) <<std::endl; // 2,T=int , but arg is int* ->T* return ;
}
结果:
1
1
2
1
2
<8>explicit specialization(深入显式特化)
显式特化不一定非得特化类,才能特化类中内容。例如下面,类Outer<void>就没特化出来,但是成员函数和一个静态变量被特化
也就是说把泛型定义的Outer里的函数和静态变量给替换了
#include <iostream> using std::cout;
using std::endl; template<typename T>
class Outer {
public:
template<typename U>
class Inner {
private:
static int count;
}; static int code; void print() const {
cout << "generic\n";
}
}; template <typename T>
int Outer<T>::code = ; template <typename T>
template <typename U>
int Outer<T>::Inner<U>::count =; template <>
class Outer<bool>
{
public:
template <typename U>
class Inner
{
private:
static int count;
}; static int code;
void print() const {
cout << " bool trait\n";
}
}; template <>
int Outer<bool>::code = ; // part of Outer<void> Specialization , but not have "Outer class definition"
template <>
int Outer<void>::code = ; template <>
void Outer<void>::print() const {
cout << "void trait\n";
}
// part of Outer<void> Specialization , but not have "Outer class definition" int main()
{
Outer<bool> val;
val.print(); cout << Outer<bool>::code <<endl;
return ;
}
<9> typedef
std::list 作为模版实参进去第二个默认参数的问题。所以std::list是不能作为默认模版的模版参数.
(1)即使我们用了typedef
template <typename T>
typedef list<T> MyList; template <typename T1, typename T2,
template <typename> class Container>
class MapList
{
public:
Container<T1> &First()
{
return mFirstList;
}
Container<T1> &Scend()
{
return mSecondList;
}
private:
Container<T1> mFirstList;
Container<T2> mSecondList;
}; int main()
{ MapList<string,int,MyList> list_01;
}
(2) C++11 ,decltype暴力用法
template <typename T1,typename T2>
??? operator+ (vector<T1> &x,vector<T2> &y)
对于这样的问题如何返回正确的vector<???>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; template <typename T1,typename T2>
auto operator+ (vector<T1> &x,vector<T2> &y) -> vector<decltype(x[]+y[])>
{
typedef decltype(x[]+y[]) types;
vector<types> temp;
temp.resize(x.size()); for(int i=;i<x.size();i++)
{
temp[i] = x[i] + y[i];
}
return temp;
}; void unit_test()
{
int ttt = ;
vector<decltype(ttt)> aaaa ;
aaaa.resize();
fill(aaaa.begin(),aaaa.end(),);
for_each(begin(aaaa),end(aaaa),[](int &val){cout << val <<endl;});
} int main()
{
vector<int> a;
vector<float> b;
a.resize();
b.resize();
fill(a.begin(),a.end(),);
fill(b.begin(),b.end(),);
auto n = a+b;
for_each(begin(n),end(n),[&n](decltype(n[]) &val){cout << val <<endl;});
return ;
}
(3)ElementT类的设计,typedef ,typename实用:
#include<iostream>
#include<vector>
#include<algorithm>
#include<initializer_list>
#include<list>
#include<stack> template <typename T>
T sumOfElements(const std::initializer_list<T> &varList)
{
T sum = ;
auto func = [&sum,&varList](const T &val)
{
sum +=val;
};
std::for_each(std::begin(varList),std::end(varList),func);
return sum;
} template <typename T>
typename std::vector<T>::value_type sumOfVector(const std::vector<T> &varList)
{
T sum = ;
auto func = [&sum,&varList](const T &val)
{
sum +=val;
};
std::for_each(std::begin(varList),std::end(varList),func);
return sum;
} // ElementT Design
template <typename T>
class ElementT; template <typename T>
class ElementT< std::vector<T> >
{
public:
typedef T TYPE;
}; template <typename T>
class ElementT< std::initializer_list<T> >
{
public:
typedef T TYPE;
}; template <typename T>
class ElementT< std::stack<T> >
{
public:
typedef T TYPE;
}; template <typename T>
typename ElementT<T>::TYPE sum_of_elements(T & container)
{
typedef typename ElementT<T>::TYPE valType;
valType sum = valType();
auto func = [&container,&sum](const valType&val)
{
sum += val;
};
std::for_each(container.begin(),container.end(),func);
return sum; } int main()
{
std::cout << "initlist->:"<<sumOfElements({,,,,,}) <<std::endl;
std::cout << "vector->: "<<sumOfVector(std::vector<int>{,,,,,}) <<std::endl;
std::cout <<"ElementT->: "<<sumOfVector(std::vector<int>{,,,,,}) <<std::endl;
return ;
}
<10>
template<char const*msg>
class Var{}
Var<"X"> 和Var<"X">其实是两个不同的实例,但是"X"实际类型是char const[2],传递给模版实参decay "char const *" type.
.
<11> 求max(1,2,3,4,3,4,1) 最大值 递归
template <typename T>
T const &tmax(const T &a,const T&b)
{
cout << "basic:"<< a <<"|"<< b <<endl;
return a<b?b:a;
} template <typename T,typename ...Args>
T const&tmax(const T&a,const T&b,const Args&... args)
{
cout<<"...args" << a <<"|"<< b <<endl;
return tmax(a,tmax(b,args...));
}; int main()
{
cout << tmax(,,) ;
//show_list(1,2,3,4,5);
return ;
}
.
C++ Template 编程,泛型编程练习的更多相关文章
- C#编程の泛型编程
什么是泛型 我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int数据,另一个是处理string数据,或者其他自定义的数据类型,但我们没有办法,只能分别写多个方法处理每个数据类型,因为 ...
- EffectiveC++ 第7章 模板与泛型编程
我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的"可能比较准确"的「翻译」. Chapter 7 模版与泛型编程 Templates and Gen ...
- linux环境下的c++编程
就C++开发工具而言,与Windows下微软(VC, VS2005等)一统天下相比,Linux/Unix下C++开发,可谓五花八门,各式各样.Emacs, vi, eclipse, anjuta,kd ...
- Effective C++ 笔记一 让自己习惯C++
条款01:视C++为一个语言联邦 C++是个多重范型编程语言,一个同时支持面向过程形式.面向对象形式.函数形式.泛型形式.元编程形式的寓言. 将C++视为几个子语言: 传统C:区块.语句.预处理器.内 ...
- Effective C++ —— 杂项讨论(九)
条款53 : 不要轻忽编译器的警告 请记住: 1. 严肃对待编译器发出的警告信息.努力在你的编译器的最高(最严苛)警告级别下争取“无任何警告”的荣誉. 2. 不要过度倚赖编译器的报警能力,因为不同的编 ...
- 《Effective C++(第三版)》-笔记
1. 让自己习惯C++ 条款01: 视C++为一个语言联邦 1.1 C++ 是一个多重泛型编程语言(multiparadigm programming),支持:过程形式(procedural),面向对 ...
- infos
C++文件流 iostream 提供了cin cout 分别用于从标准输入读取流和向标准输出写入流cout 标准输出 屏幕 输出写入fstream文件流 cin 从标准输入读取cout 向标准输入写入 ...
- Effective C++ 条款一 视C++为一个语音联邦
1.C语言 区块.语句.预处理器.内置数据类型.数组.指针等内容 2.OC++ 类.封装.继承.多态.virtual函数 等 3.Template C++ 泛型 ...
- 【C++】从设计原理来看string类
1.一些C++基础知识 模板类string的设计属于底层,其中运用到了很多C++的编程技巧,比如模板.迭代器.友元.函数和运算符重载.内联等等,为了便于后续理解string类,这里先对涉及到的概念做个 ...
随机推荐
- 2018ccpc秦皇岛站后记
总的来说这不是一场体验十分好的比赛. 定的宾馆有一点小,学校提供的伙食人太多了,不想排队,饭票又不能换香蕉,就没有吃. 到的第一天遇到了价格向上取整和到站不打发票的两个黑车司机,让我对这个地点好感大减 ...
- 2018ccpc湖南邀请赛后记
第一次出省去打邀请赛,赛前给队友定的目标是打个铜,这样奖金就可以报销我们的伙食费了 5.12 热身赛,ak的心态冲进去,爆零逃出来 (为什么热身赛没有签到题啊),出来一度以为这场比赛要打铁,毕竟老远过 ...
- python多重继承的钻石问题
如下,我们已经有了一个从Contact类继承过来的Friend类 class ContactList(list): def search(self, name): '''Return all cont ...
- 剑指Offer_编程题_6
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个 ...
- 最接近原点的K个点
一.题目描述 我们有一个由平面上的点组成的列表 points.需要从中找出 K 个距离原点 (0, 0) 最近的点 这里,平面上两点之间的距离是欧几里德距离 你可以按任何顺序返回答案.除了点坐标的顺序 ...
- Python基础01
Python基础 1.Python介绍 2.安装 3.Hello World程序 4.变量 5.用户输入 6.表达式if ...else语句 7.表达式for 循环 8.表达式while 循环 9.数 ...
- python dom操作
1.DOM介绍 (1)什么是DOM DOM:文档对象模型.DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构.目的其实就是为了能让js操作html元素而制定的一个规范. DOM就是由节 ...
- [NIO-1]缓冲区
常用的是ByteBuffer.CharBuffer
- ubuntu主题收集
ubuntu主题收集 一些cmd常用命令: 任务栏底部,进入Dash并打开终端,命令最后一个是参数可选 ( Left | Bottom ) gsettings set com.canonical.Un ...
- vue项目中引用jquery
1.使用npm安装 npm i jquery --S //jquery要小写 2.在package.json文件dependencies里面加入jq 3.在build文件夹的webpack.base. ...