美文网首页
泛型与模版的应用

泛型与模版的应用

作者: 陈道乐 | 来源:发表于2018-10-19 21:39 被阅读0次

泛型编程即以一种独立于任何特定类型的方式编写代码。

模板类型

一,模板参数

指定形式参数类型和返回参数类型, 模板参数不允许自动类型转换

template<typename T1, typename T2, typename RT>
inline RT max(const T1& a, const T2& b)
{
    return a > b? a:b;
}

int main()
{
    int a, b;
    a = 1;
    b = 2;
    max<int, int, double>(a,b);
}

二,模板函数

#include <iostream>
#include <string>

//typename 意义时说明,T 是一个数据类型,不是一个类或者成员变量, 或者成员函数。并非强制使用typename, class同样可以替换wq
template <typename T>

inline T func(T& t) {
    return  t;
}

using namespace std;

int main() {
    string  hello = "hello";

    //编译器猜测类型
    cout << func(hello) << endl;

    //指明类型
    cout << func<string>(hello) << endl;

    return  0;
}
1.隐式指定
template <typedef T>
const T& max(const T& a, const T& n)
{
    retun a > b ? a :b;
}

int main()
{
    int a, b;
    a = 1;
    b = 4;
    //隐式转换
    max(a, b);
    return 0;
}
2.显式转换
template <typedef T>
const T& max(const T& a, const T& n)
{
    retun a > b ? a :b;
}

int main()
{
    int a, b;
    a = 1;
    b = 4;
    //显式转换
    max<int>(a, b);
    return 0;
}
3.数据类型强制转换
template <typedef T>
const T& max(const T& a, const T& n)
{
    retun a > b ? a :b;
}

int main()
{
    int a;
    double b;
    a = 1;
    b = 4.0;
    //隐式转换
    max<double>(static_cast<double>a, b);
    return 0;
}

三, 模板重载函数

inline const int& max(const int& a, const int& b)
{
    return a > b ? a : b;
}

template<typename T>
inline const T& max(const T& a, const T& b)
{
    return a > b? a: b;
}

template<typename T>
inline const T& max(const T& a, const T& b, const T& c)
{
    return max(max(a, b), c);
}

int main()
{
    max(1, 7); //调用int 类型的重载函数
    max(1, 2, 3); //调用三个参数䣌模板
    return 0;
}

三,类模板

#include <iostream>
#include <string>

using namespace std;

template <class T>

class Hello {
    public:
        void say(const T& t) {
            cout << t << endl;
        }
};

int main() {
    Hello<string>* hello = new Hello<string>();

    hello->say("hello");

    return  0;
}
模版定义和实现分离时
//test.h
template <class T>
class Test
{
public:
    void print(T& t);
}

//test.cpp, 需要再次声明T
template <class T>
void Test<T>::print(T&t)
{
    std::cout << t << std::endl;
}

高级

二次定义模版

template <class T, class NewT = std::queue<T>>

模板元编程

1.用于编译开关部分代码使用

//一个支持透明色的32bit blit函数
template<const bool useMask>
void blit(int& dst, const int* src, int mask, size_t size)
{
    for(size_t = 0; i < size; i++, dst++, src++)
    {
        if(!useMask || *src != mask) 
        {
            *dst = *src;
        }
    }
}


void main()
{
   //关闭或开启, 编译时期确定
    blit<true>(....)
}

  1. 递归算法优化

将指数级运算,降低到常数级运算

//被优化算法
unsigned int fib(unsigned int n)
{
    if (n == 0 || n == 1) {
        return 1;
    } 
    else
    {
        return fib(n -1) + fib(n-2);
    }
}

//优化后算法

template<unsigned int N>
struct FibR
{
    enum
    {
        Val = FibR<N-1>::Val + FibR<N-2>::Val
    };
    
}

//定义模板确定常量时,的格式
template <>
struct FibR<0>
{
    enum
    {
        Val = 1;
    }
}

template <>
struct FibR<1>
{
    enum
    {
        Val = 0;
    }
}
//定义为一个函数,记得传递n
#define fib(n) FibR<n>::Val

可变参数模板

#include <iostream>

void showall()
{
    return;
}

template <typename R1, typename... Args>
void showall(R1 var, Args... args)
{
    std::cout << var << std::endl;
    showall(args...);
}

int main(int argc, char* args[])
{
    //传递参数数字
    showall(1 ,2 ,3, 4);
    
    //传递字符
    showall("a", "b", "c");
    
    //混合传递
    showall(1 ,"abc", 2);
    return 0;
}

仿函数中的应用

#include <iostream>
#include <functional>

template <typename R1, typename R2>
struct Calc
{
    void add(R1 a)
    {
        std::cout << a <<std::endl;
    }

    void add_1(R1 a, R2 b)
    {
        std::cout << a + b << std::endl;
    }
};


int main(int argc, char* args[])
{
    void (Calc<int, double>::* fc)(int) = &Calc<int, double>::add;

    //实际上不能用
    //fc(25);

    Calc<int, double > calc;

    auto fun = std::bind(&Calc<int, double>::add, &calc, std::placeholders::_1);
    std::function<void(int, double)> fun2 = std::bind(&Calc<int,  double>::add_1, &calc, std::placeholders::_1, std::placeholders::_2);

    fun(25);
    fun2(1, 25);

    return 0;
}

使用using, 函数指针, typedef来实现函数调用

#include <iostream>
#include <stdlib.h>

int calc()
{
    return 0;
}

template <typename R1, typename... Args>
int calc(R1 a, Args... args)
{
    return  a + calc(args...);
}

int main(int argc, char* args[])
{
    int(* fun)(int, int, int) = calc;
    std::cout << fun(1, 1, 1) << std::endl;
    system("echo 使用函数指针");


    typedef int(*Add)(int, int, int);
    Add Gadd = calc;
    std::cout << Gadd(2, 2, 2) << std::endl;
    system("echo 使用typedef实现");

    using Func = int(*)(int, int, int);
    Func func = calc;
    std::cout << func(3, 3, 3) << std::endl;
    system("echo 使用using实现");

    return 0;
}

相关文章

  • 泛型与模版的应用

    泛型编程即以一种独立于任何特定类型的方式编写代码。 模板类型 一,模板参数 指定形式参数类型和返回参数类型, 模板...

  • GeekBand STL与泛型编程 First Week

    GeekBand STL与泛型编程 First Week 泛型编程 模版介绍 模版是C++的一种特性,允许函数或类...

  • 探秘 Java 中的泛型(Generic)

    本文包括:JDK5之前集合对象使用问题泛型的出现泛型应用泛型典型应用自定义泛型——泛型方法自定义泛型——泛型类泛型...

  • 31,泛型

    泛型就是参数化类型 适用于多种数据类型执行相同的代码泛型中的类型在使用时指定泛型归根到底就是“模版”优点:使用泛型...

  • Web笔记-基础加强

    泛型高级应用 自定义泛型方法 自定义泛型类 泛型通配符? 泛型的上下限 泛型的定义者和泛型的使用者 泛型的定义者:...

  • Java 泛型

    泛型类 例如 泛型接口 例如 泛型通配符 泛型方法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型上下边...

  • 泛型简单的应用总结:

    泛型可以应用在类,方法,接口中,可以定义泛型类,泛型方法,泛型接口三种 利用泛型的好处: 可以有效的减少代...

  • 【泛型】通配符与嵌套

    上一篇 【泛型】泛型的作用与定义 1 泛型分类 泛型可以分成泛型类、泛型方法和泛型接口 1.1 泛型类 一个泛型类...

  • 泛型的使用

    泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法 泛型类 泛型接口 泛型通配符 泛型方法 静态方法与...

  • 重走安卓进阶路——泛型

    ps.原来的标题 为什么我们需要泛型? 泛型类、泛型接口和泛型方法(泛型类和泛型接口的定义与泛型方法辨析); 如何...

网友评论

      本文标题:泛型与模版的应用

      本文链接:https://www.haomeiwen.com/subject/rewuzftx.html