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>的更多相关文章

  1. 解决Windows版Git出现templates not found的问题

    环境: Win10 x64 Git windows客户端(下载自 https://git-scm.com/) SourceTree 1.9.6.1(使用系统安装的Git,而非SourceTree内嵌的 ...

  2. [c++] Templates

    Template是编译时多态.所有的模板都是在编译时产生对应的代码,它没有面向对象中的虚表,无法实现动态多态. Function Template A function template is a p ...

  3. webstrom live templates

    javascript: 在live templates底部要选择javascript # $('#$END$') $ $($end$) $bd $(document.body) $d $(docume ...

  4. Myeclipse Templates详解(一) —— Java模板基础

    目录 Templates简介 MyEclipse自带Templates详解 新建Template 自定义Template 因为自己比较懒,尤其是对敲重复代码比较厌恶,所以经常喜欢用快捷键和模板,Mye ...

  5. Using FreeMarker templates (FTL)- Tutorial

    Lars Vogel, (c) 2012, 2016 vogella GmbHVersion 1.4,06.10.2016 Table of Contents 1. Introduction to F ...

  6. juqery模板 Templates

    现在已经有了许多JavaScript的解决方案模板,从这方面说,标准化的模板解决方案必然是大势所趋.在本节中,我们向你简要描述四个最流行最有趣的模板.现有的模板解决方案能解决什么?那些特色在jQuer ...

  7. django TEMPLATES

    ?: (1_8.W001) The standalone TEMPLATE_* settings were deprecated in Django 1.8 and the TEMPLATES dic ...

  8. django复习笔记3:urls/views/templates三板斧

    0.先看看文件结构 mysite/ mysite/ ├── __pycache__ │   └── manage.cpython-.pyc ├── blog │   ├── __init__.py │ ...

  9. Effective C++ -----条款44:将与参数无关的代码抽离templates

    Templates生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系. 因非类型模板参数(non-type template para ...

  10. 第三节:视图(Views)和模板(Templates)

    目录 概览 编写视图 编辑视图实际做一些事情 抛出404异常 使用模板系统 移除在代码中的硬编码网址 Url名称的命名空间 概览 视图是Django应用的网页的“类型”,一般服务于特定的功能并且有特定 ...

随机推荐

  1. 剑指Offer_编程题_2

    题目描述 请实现一个函数,将一个字符串中的空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy.   class Solution ...

  2. 信用评分卡 (part 6 of 7)

    python信用评分卡(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_camp ...

  3. Dubbo简易控制中心安装

    1. zookeeper安装(单机版):http://www.cnblogs.com/wangfajun/p/5251159.html  √ 2. dubbo管控台安装(zookeeper单机版):h ...

  4. JAVA-集合类型List(ArrayList、LinkedList)常用操作例子(基础必备)

    package com.net.xinfang.reflect; import java.util.ArrayList; import java.util.Arrays; import java.ut ...

  5. Ubuntu18.04 关闭和开启图形界面

    关闭用户图形界面,使用tty登录. sudo systemctl set-default multi-user.target sudo reboot 开启用户图形界面. sudo systemctl ...

  6. thymeleaf 基础

    (一)Thymeleaf 是个什么?      简单说, Thymeleaf 是一个跟 Velocity.FreeMarker 类似的模板引擎,它可以完全替代 JSP .相较与其他的模板引擎,它有如下 ...

  7. npm与nrm

    npm npm是Node.js 平台的默认包(模块依赖)管理工具 Node Package Manager nrm 一个npm的源管理器(管理工具) 允许快速的在 npm 源间切换 两者关系 npm是 ...

  8. vue中异步函数async和await的用法

    整理的不错,收藏一下 http://blog.sina.com.cn/s/blog_13d06fc1f0102wzfr.html

  9. ****** 四十 ******、软设笔记【网络基础】-Internet和Intranet基础

    Internet和Intranet基础 一.网络地址及子网掩码 1.IP地址结构及类别 IP地址是由32位二进制数,即4个字节组成的,由网络号和主机号两个字段组成. 网络号的位数决定了可以分配的网络数 ...

  10. ssh免密登录及去掉提示

    A连B 1.生成公钥和私钥    ssh-keygen2.复制公钥到需要免密登录的服务器上  ssh-copy-id root@192.168.25.175 A连A 2.复制公钥到本机上  ssh-c ...