Templates<2>
Part:template specialized
Part1:template specialized
#include <iostream>
#include <stdio.h>
using namespace std;
template <typename To,typename From>
struct CastAndPrint
{
CastAndPrint(From f){
cout << (To)f <<endl;
}
}; template <typename To>
struct CastAndPrint<To,const char*>
{
CastAndPrint(const char *s){
cout << (To)atoi(s) <<endl;
}
}; int main()
{
CastAndPrint<int,float>(1.232f);
CastAndPrint<int,const char*>("");
CastAndPrint<char,const char*>("");
return ;
}
part2:Trait & Policy
(1) accumulation,可能的累积定义
//
// Created by Administrator on 2017/8/12.
// #ifndef TP_CP15_ACCUM_ACCUMTRAITS_H
#define TP_CP15_ACCUM_ACCUMTRAITS_H #include <iostream> template <typename T>
class AccumulationTraits; template <>
class AccumulationTraits<char>
{
public:
typedef int AccT;
}; template <>
class AccumulationTraits<short>
{
public:
typedef int AccT;
}; template <>
class AccumulationTraits<int>
{
public:
typedef int AccT; }; template <>
class AccumulationTraits<float>
{
public:
typedef double AccT; }; #endif //TP_CP15_ACCUM_ACCUMTRAITS_H
accumtraits.h
#ifndef TP_CP15_ACCUM_ACCUM2_H
#define TP_CP15_ACCUM_ACCUM2_H #include <iostream>
#include "accumtraits.h"
template <typename T> typename
AccumulationTraits<T>::AccT accum(T const*begin,T const*end)
{
typedef typename AccumulationTraits<T>::AccT AccT;
AccT total = AccT();
while(begin!=end)
{
total += *begin;
++begin;
}
return total;
} #endif //TP_CP15_ACCUM_ACCUM2_H
accum2.h
#include <iostream>
#include "accum2.h"
using namespace std;
int main()
{ int val[]{,,,,};
cout << accum(val,val+) <<endl; char val2[] = "AA";
cout << accum(val2,val2+) <<endl; // return ;
}
main.cpp
(2) Trait 和 Policy为我们的程序提供一个用户可以编辑的模版接口
accumlation.h把所有的定义都写了
//
// Created by Administrator on 2017/8/13.
// #ifndef TP_CP15_ACCUMTRAITS2_ACCUMULATION_H
#define TP_CP15_ACCUMTRAITS2_ACCUMULATION_H // ============================ Traits ===============================
template <typename T>
class AccumulationTraits; template <>
class AccumulationTraits<char>
{
public:
typedef int AccT;
static AccT zero() { return ;}
}; template <>
class AccumulationTraits<int>
{
public:
typedef int AccT;
static AccT zero() { return ;}
}; template <>
class AccumulationTraits<short>
{
public:
typedef int AccT;
static AccT zero() { return ;}
}; template <>
class AccumulationTraits<unsigned int>
{
public:
typedef unsigned long AccT;
static AccT zero() { return ;}
}; template <>
class AccumulationTraits<float>
{
public:
typedef float AccT;
static AccT zero() { return 0.0f;}
}; // ============================ Traits =============================== // define one Simple Policy for our defaults
class SumPolicy
{
public:
template <typename T1,typename T2>
static void accumulate (T1 &total, T2 const &value)
{
total += value;
}
}; //
template <typename T,
typename Policy = SumPolicy,
typename Traits = AccumulationTraits<T> >
class Accum
{
public:
typedef typename Traits::AccT AccT;
static AccT accum(T const*begin, T const *end)
{
AccT total = Traits::zero();
while (begin!=end)
{
Policy::accumulate(total,*begin);
begin++;
}
return total;
}
}; #endif //TP_CP15_ACCUMTRAITS2_ACCUMULATION_H
accumlation.h
main.cpp提供了2个新Policy接口,但是我们的乘法接口会出现问题,因为初值zero()
#include <iostream>
#include "accumulation.h" //
class DoubleAddPolicy
{
public:
template <typename T1,typename T2>
static void accumulate(T1 &total , T2 const &value)
{
total += * value;
}
}; class MultPolicy
{
public:
template <typename T1,typename T2>
static void accumulate(T1 &total , T2 const &value)
{
total *= value;
}
}; using namespace std;
int main()
{
int val[]{,,,,,};
cout << Accum<int>::accum(val,val+) <<endl; char cval[] = "AA";
cout << Accum<char>::accum(cval,cval+)<<endl; float fval[]{1.0,2.0,3.0,4.0,5.0};
cout << Accum<float>::accum(fval,fval+)<<endl; cout << Accum<float,DoubleAddPolicy>::accum(fval,fval+) <<endl; // but next result will is zero,because our value initialized to zero
cout << Accum<float,MultPolicy>::accum(fval,fval+) <<endl;
return ;
}
main.cpp
Part3:Type function
(1) 确定容器元素类型
#include <iostream>
#include <vector>
#include <stack>
#include <typeinfo>
#include <list>
using namespace std; // class give the type size
template <typename T>
class TypeSize
{
public:
static size_t const value = sizeof(T);
}; // what element type in a container
template <typename T>
class ElementT; // basic template // vector<>
template <typename T>
class ElementT<vector<T>>
{
public:
typedef T type;
}; // list<>
template <typename T>
class ElementT<list<T>>
{
public:
typedef T type;
}; // stack<>
template <typename T>
class ElementT<stack<T>>
{
public:
typedef T type;
}; template <typename T>
void print_element(T const &c)
{
cout << "Container of " << typeid(typename ElementT<T>::type).name() << endl;
} // but lots of containers have it's own value_type,so we can use this method
template <typename T>
void print_valueType(T const &c)
{
cout << "Container of " << typeid(typename T::value_type).name()<< endl;
} int main()
{
cout << TypeSize<char>::value <<endl;
cout << TypeSize<short>::value <<endl;
stack<int> s;
vector<float> s2;
print_element(s);
print_element(s2);
print_valueType(s2); return ;
}
(2) Why the container::value_type is import?
检查一个类型是类,还是不是类(SFINAE,substitution-failure-is-not-error,替换失败并非错误):
#include <iostream> template <typename T>
class IsClassT
{
private:
typedef struct {char a[];} char2;
template <typename C>
static char test(int C::*); template <typename C>
static char2 test(...); public:
enum{Yes=sizeof(IsClassT<T>::test<T>()) == };
enum{No = !Yes}; };
template <typename T>
void check()
{
if(IsClassT<T>::Yes)
{
std::cout << "IsClassT" <<std::endl;
}
else
{
std::cout << "!IsClassT" <<std::endl;
} }
class Data
{ }; int main()
{
check<int>();
check<Data>();
return ;
}
具体(SFINAE)解释程序:
#include <iostream>
using namespace std; typedef struct char2
{
char a[];
}char2; template <typename T>
char test(int T::*); template <typename T>
char2 test(...); class Value
{ }; int main(int argc, char const *argv[])
{
std::cout <<sizeof(char) <<endl; //
std::cout <<sizeof(char2) <<endl; // std::cout << sizeof(test<int>()) << endl; // 2,select test(...) function
std::cout << sizeof(test<Value>()) << endl; // 1,select test(int T::*) function return ;
}
Promotion trait:
#ifndef INC_15_2_4_IFTHENELSE_HPP_H
#define INC_15_2_4_IFTHENELSE_HPP_H template <bool C, typename Ta , typename Tb>
class IfThenElse; template <typename Ta,typename Tb>
class IfThenElse<true,Ta,Tb>
{
public:
typedef Ta value_type;
}; template <typename Ta,typename Tb>
class IfThenElse<false,Ta,Tb>
{
public:
typedef Tb value_type;
}; #endif //INC_15_2_4_IFTHENELSE_HPP_H
ifthenelse.hpp
#ifndef PROMOTE_HPP_H_
#define PROMOTE_HPP_H_
#include <vector>
#include "ifthenelse.hpp" template <typename T1,typename T2>
class Promotion; template <typename T1,typename T2>
class Promotion
{
public:
typedef typename IfThenElse<(sizeof(T1) > sizeof(T2)),T1,T2>::value_type value_type;
}; template <typename T>
class Promotion<T,T>
{
public:
typedef T value_type;
}; template <typename T1,typename T2>
class Promotion<std::vector<T1>,std::vector<T2>>
{
public:
typedef std::vector<typename Promotion<T1,T2>::value_type > value_type;
}; template <typename T>
class Promotion<std::vector<T>,std::vector<T>>
{
public:
typedef std::vector<typename Promotion<T,T>::value_type > value_type;
}; #endif
promote.hpp
#include <iostream>
#include "promote.hpp"
#include <algorithm>
using namespace std;
template <typename T1,typename T2>
typename Promotion<T1,T2>::value_type add(T1 val1,T2 val2)
{
return val1+val2;
} template <typename T1,typename T2>
typename Promotion<vector<T1>,vector<T2>>::value_type add(const vector<T1> &val1,
const vector<T2> &val2)
{
typename Promotion<vector<T1>,vector<T2>>::value_type result;
for(int i=;i<val1.size();i++)
{
result.push_back(val1[i] + val2[i]);
}
return result;
}; int main()
{
std::cout <<add(,2.0f)<< std::endl;
vector<int> val_01();
fill(val_01.begin(),val_01.end(),);
vector<float> val_02();
fill(val_02.begin(),val_02.end(),2.0f);
auto result = add(val_01,val_02); // vector<float>
for_each(result.begin(),result.end(),[](const float &val){cout << val << endl;}); return ;
}
main.cpp
Metaprogram:
<1>计算一个数的n次方
#include <iostream> template <int S,int N>
class pow
{
public:
enum {result = S*pow<S,N->::result};
}; template <int S>
class pow<S,>
{
public:
enum{result = };
}; template <int N>
class pow<,N>
{
public:
enum{result};
}; template <>
class pow<,>
{
public:
enum{ result};
}; int main()
{
std::cout << pow<,>::result <<std::endl; // 3^2
std::cout << pow<,>::result <<std::endl; // 2^2
return ;
}
上面的代码依然可以用static int const result 代替:
#include <iostream> template <int S,int N>
class pow
{
public:
static const int result = S*pow<S,N->::result;
}; template <int S>
class pow<S,>
{
public:
static const int result = ;
}; template <int N>
class pow<,N>
{
public:
static const int result = ;
}; template <>
class pow<,>
{
public:
static const int result = ;
}; int main()
{
std::cout << pow<,>::result <<std::endl; // 3^2
std::cout << pow<,>::result <<std::endl; // 2^2
return ;
}
不过static int 出来的数据永远是个左值。
<2>For循环展开:
(1)图形学dot()函数
#include <iostream>
template <int DIM, typename T>
class DotProduct
{
public:
static T result(T *a,T *b)
{
return (*a) * (*b) + DotProduct<DIM-,T>::result(a+,b+);
}
};
template <typename T>
class DotProduct<,T>
{
public:
static T result(T *a,T*b)
{
return (*a) * (*b);
}
}; int main() {
float a[] = {,,};
float b[] = {,,};
std::cout << DotProduct<,float>::result(a,b) << std::endl;
return ;
}
(2)求数组合和数组乘积Accumulate
enum Accumulate_Type
{
ADD,
Mutiply,
}; template <int N,typename T,Accumulate_Type Type=ADD>
class Accumulate
{
public:
static T result(T *data)
{
if(Type == Accumulate_Type::ADD)
return *data + Accumulate<N-,T,Type>::result(data+);
return *data * Accumulate<N-,T,Type>::result(data+);
}
}; template <typename T,Accumulate_Type Type>
class Accumulate<,T,Type>
{
public:
static T result(T *data)
{
return *data;
}
}; void testAccumulate()
{
float a[] = {,,};
std::cout << "Mutiply:"<<Accumulate<,float,Accumulate_Type::Mutiply>::result(a)<<std::endl;
std::cout << "Add:" <<Accumulate<,float,Accumulate_Type::ADD>::result(a)<<std::endl;
}
表达式模版:
一个疑问点:一个简单的模版类:
下面两种方案都一样:
Simple<T>& operator= (Simple<T> const &b)
{
std::cout << "operator= " << "a:" << this << "b:" <<&b <<std::endl;
val = b.val;
}
Simple& operator= (Simple const &b)
{
std::cout << "operator= " << "a:" << this << " b:" <<&b <<std::endl;
val = b.val;
}
类定义全部定义:
template <typename T>
class Simple
{
public:
T val; Simple(T m):val(m)
{ } /*
Simple<T>& operator= (Simple<T> const &b)
{
std::cout << "operator= " << "a:" << this << "b:" <<&b <<std::endl;
val = b.val;
}
*/ Simple& operator= (Simple const &b)
{
std::cout << "operator= " << "a:" << this << " b:" <<&b <<std::endl;
val = b.val;
} void debug()
{
std::cout << "value :" << val <<std::endl;
}
}; int main()
{
Simple<int> a();
Simple<int> b();
a = b;
a.debug();
return ;
}
结果:
A:0x22fe40
B:0x22fe30
operator= a:0x22fe40 b:0x22fe30
value :11
如何修改函数对象的内容通过for_each()
#include <iostream>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std; template <typename T>
class init_map
{
public:
void operator()(const T &rh){
m[m.size()] = rh;
}
T operator[](const int i)
{
return (*(m.find(i))).second;
} friend ostream& operator<<(ostream &os, init_map <T>&v)
{
for(auto iter=v.m.begin(); iter!= v.m.end();iter++)
{
cout << (*iter).second <<endl;
} return os;
} private:
map<int ,T> m;
}; int main()
{
float f[] = {1.1f ,2.1f, 3.1f, 4.1f, 5.1f, 6.1f, 7.1f, 8.1f ,9.1f};
int counts = floor(sizeof(f)/sizeof(float));
init_map <float> mv; // make a function that point to your init_map object
auto func = [&mv](float v){
mv(v);
}; for_each(f,f+counts,func);
cout << mv; return ;
}
....
Templates<2>的更多相关文章
- 解决Windows版Git出现templates not found的问题
环境: Win10 x64 Git windows客户端(下载自 https://git-scm.com/) SourceTree 1.9.6.1(使用系统安装的Git,而非SourceTree内嵌的 ...
- [c++] Templates
Template是编译时多态.所有的模板都是在编译时产生对应的代码,它没有面向对象中的虚表,无法实现动态多态. Function Template A function template is a p ...
- webstrom live templates
javascript: 在live templates底部要选择javascript # $('#$END$') $ $($end$) $bd $(document.body) $d $(docume ...
- Myeclipse Templates详解(一) —— Java模板基础
目录 Templates简介 MyEclipse自带Templates详解 新建Template 自定义Template 因为自己比较懒,尤其是对敲重复代码比较厌恶,所以经常喜欢用快捷键和模板,Mye ...
- Using FreeMarker templates (FTL)- Tutorial
Lars Vogel, (c) 2012, 2016 vogella GmbHVersion 1.4,06.10.2016 Table of Contents 1. Introduction to F ...
- juqery模板 Templates
现在已经有了许多JavaScript的解决方案模板,从这方面说,标准化的模板解决方案必然是大势所趋.在本节中,我们向你简要描述四个最流行最有趣的模板.现有的模板解决方案能解决什么?那些特色在jQuer ...
- django TEMPLATES
?: (1_8.W001) The standalone TEMPLATE_* settings were deprecated in Django 1.8 and the TEMPLATES dic ...
- django复习笔记3:urls/views/templates三板斧
0.先看看文件结构 mysite/ mysite/ ├── __pycache__ │ └── manage.cpython-.pyc ├── blog │ ├── __init__.py │ ...
- Effective C++ -----条款44:将与参数无关的代码抽离templates
Templates生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系. 因非类型模板参数(non-type template para ...
- 第三节:视图(Views)和模板(Templates)
目录 概览 编写视图 编辑视图实际做一些事情 抛出404异常 使用模板系统 移除在代码中的硬编码网址 Url名称的命名空间 概览 视图是Django应用的网页的“类型”,一般服务于特定的功能并且有特定 ...
随机推荐
- jmeter源码导入eclipse步骤
1.新建标准java项目2.右击项目选import filesystem 将apache-jmeter-4.0整个目录勾选allow output folders for source folders ...
- busybox(一)浅析
目录 busybox(一)浅析 引入 读取inittab 创建执行脚本链表 执行脚本 小结 title: busybox(一)浅析 tag: arm date: 2018-11-13 23:02:33 ...
- Jenkins权限分配
做完Jenkins安装.项目自动化打包部署后,当然需要对小组成员进行项目权限的分配 1.安装插件:Role-based Authorization Strategy(安装过程就展示了): 2. 插件装 ...
- Leetcode 137 Single Number II 仅出现一次的数字
原题地址https://leetcode.com/problems/single-number-ii/ 题目描述Given an array of integers, every element ap ...
- HDU 1030(三角数阵 数学)
题意是问在给定的三角形数阵中从一个数到另一个数所要跨过的边数. 最初的时候很迷,除了发现每层的数字个数与层数间的关系和每层数最后一个数与层数的关系外什么也没看出来,打算先求出数字所在的层数,然后计算到 ...
- Redis学习笔记(二)解析dump.rdb文件工具之redis-rdb-tools
https://github.com/sripathikrishnan/redis-rdb-tools 我这里使用docker搭建 docker搭建文档 https://rdbtools.com/do ...
- 很好的sql多表
oracle 多表联合查询总结归纳 2018年08月16日 20:57:39 阅读数:44905 本次预计讲解的知识点 1. 多表查询的操作.限制.笛卡尔积的问题: 2. 统计函数及分组统计的操作: ...
- yum 安装时错误 Errno 14 Couldn't resolve host 解决办法
后来网上查了一下说是DNS服务器错误.于是修改一下 /etc/resolv.conf 添加一个nameserver 8.8.8.8完成
- 用过企业微信APP 后,微信接收不到消息,解决方案
用过企业微信APP 后,微信接收不到消息的,怎么办? 请打开企业微信,找到:我----设置----新消息通知----仅在企业微信中接收消息
- php中inset 和 和 empty 的区别
inset函数 用途:检测变量是否设置判断:检测变量是否设置,并且不是 NULL.如果已经使用 unset() 释放了一个变量之后,它将不再是 isset().若使用 isset() 测试一个被设置成 ...