zoukankan      html  css  js  c++  java
  • c++模板笔记

    使用vc2015
    进行C++ 模板的学习实验和笔记 用简单示例学习了解STL


    template大部头理论书 讲解各种规则和各种规则例外的解决办法 集中精力在20%的规则中的阴暗角落而不是80%实践中要注意的东西

    https://github.com/wuye9036/CppTemplateTutorial
    这个模板教程是强烈推荐 易懂 看完可用于个人的一些代码中进行模板编程 实用


    第一个示例
    //=============================================
    int add(int a ,int b)
    {
    return a+b;
    }

    int main()
    {
    add(3,8);
    add(7,12);
    return 0;
    }
    //============================================
    如果说
    函数是变量之间的操作方式复用方案
    比如 3+8 7+12 都是调用add函数
    那么模板就是变量的类型的复用方案
    比如

    #include <iostream>
    template<typename T>
    const T& compare(T& a, T& b)
    {
    return a > b? a :b;
    }

    int main()
    {
    int a = 7, b = 8, c = 9, d = 3;
    std::cout << compare<int>(a, b) << std::endl;
    std::cout << compare(c, d) << std::endl;
    char f = 'f', g = 'z';
    std::cout << compare(f, g) << std::endl;
    return 0;
    }

    compare这个模板函数对于变量的比较方式都是一致的 ,就是比较两个变量的大小
    而且对于 int 和 char 两种变量类型的比较都适用
    就是我所说的对于变量的类型的复用方案
    由于模板T对应的变量类型在本例中可以从函数参数推导得出 所以<int>这个符号并不强制需要写出来。

    下面示例是一个链表 链表中每个节点可以存储不同类型元素
    #include <iostream>
    #include <string>

    template<typename TYPE,typename NEXT>
    struct AnyList {
    TYPE value;
    NEXT* next;
    AnyList(TYPE const &v,NEXT *n):value(v),next(n){}
    };

    int main()
    {
    typedef AnyList<int, void> node_0;
    node_0 zero(4,NULL) ;
    typedef AnyList<char, node_0> node_1;
    node_1 one('z',&zero);
    typedef AnyList<std::string, node_1> node_2;
    node_2 two("test", &one);

    std::cout << two.value << std::endl;
    std::cout << one.value << std::endl;
    std::cout << zero.value << std::endl;

    std::cout << two.value << std::endl;
    std::cout << two.next->value << std::endl;
    std::cout << two.next->next->value << std::endl;

    return 0;
    }

    示意图:略

    STL中FOREACH示例学习(函数指针模板参数)
    #include <iostream>
    #include <string>

    template<typename T,void(*f)(T &v)>
    void foreach(T array[], unsigned size)
    {
    for (unsigned i = 0; i < size; ++i)
    f(array[i]);
    }

    template<typename T>
    void inc(T& v) { ++v; }

    template<typename T>
    void dec(T& v) { --v; }

    template<typename T>
    void print(T& v) { std::cout << ' ' << v << std::endl; }

    int main()
    {
    int array[] = { 1,2,3,4,5,6,7,8 };

    foreach<int, print<int>>(array, 8);
    std::cout << std::endl;

    foreach<int, inc<int>>(array, 8);
    foreach<int, print<int>>(array, 8);
    std::cout << std::endl;

    foreach<int, dec<int>>(array, 8);
    foreach<int, print<int>>(array, 8);
    std::cout << std::endl;

    return 0;
    }
    FOREACH函数从模板接收操作类型和操作函数,从参数中接收要操作的数组和数组长度
    //===============================================
    指针与引用模板参数

    #include <iostream>
    #include <string>

    template<typename T>
    class wrapper;

    template<typename T>
    class wrapper<T*> {
    public:
    T* p;
    wrapper(T* t):p(t){}
    T get() { return *p; }
    void set(T v) { *p = v; }
    };


    template<typename T>
    class wrapper<T&> {
    public:
    T& p;
    wrapper(T& t) :p(t) {}
    T get() { return p; }
    void set(T v) { p = v; }
    };


    int global_variable_int = 0;

    char global_variable_char = 'Z';

    std::string global_variable_str = "this is a test";

    int main()
    {

    wrapper<int*> gwrapper1(&global_variable_int);
    gwrapper1.set(1);
    std::cout << gwrapper1.get() << std::endl;

    wrapper<int&> gwrapper2(global_variable_int);
    gwrapper2.set(2);
    std::cout << gwrapper2.get() << std::endl;

    wrapper<char*> gwrapper3(&global_variable_char);
    gwrapper3.set('a');
    std::cout << gwrapper3.get() << std::endl;

    wrapper<char&> gwrapper4(global_variable_char);
    gwrapper4.set('g');
    std::cout << gwrapper4.get() << std::endl;

    wrapper<std::string*> gwrapper5(&global_variable_str);
    std::cout << gwrapper5.get() << std::endl;

    wrapper<std::string&> gwrapper6(global_variable_str);
    gwrapper6.set("finish test");
    std::cout << gwrapper6.get() << std::endl;

    return 0;
    }

    根据参数的不同 自动选择不同的模板函数 指针或者引用
    //======================================
    模板的模板参数
    如果模板中的模板不参与推导 可以省略不写
    #include <iostream>
    #include <string>

    //template<template<typename TT> class Func, typename T>
    template<template<typename> class Func, typename T>
    void foreach(T array[], unsigned size)
    {

    Func<T> func;
    for (unsigned i = 0; i < size; ++i)
    func(array[i]);
    }

    template<typename T>
    struct inc {
    void operator()(T& v) { ++v; }
    };

    int main()
    {
    int arr[] = { 1,2,3,4,5 };
    foreach<inc>(arr,5);
    return 0;
    }

    //====================================================
    特化匹配示例
    // 11111.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"
    #include <iostream>
    #include <string>

    template<typename T0,typename T1,typename T2>
    struct S {
    std::string id() { return "General"; }
    };

    template<typename T0,typename T1>
    struct S<T0, T1, char>
    {
    std::string id(){ return "#1"; }
    };

    template<typename T0>
    struct S<T0, char, char>
    {
    std::string id() { return "#2"; }
    };

    template<typename T>
    struct S<int, T, T>
    {
    std::string id() { return "#3"; }
    };


    int main()
    {
    std::cout << S<float, float, float>().id() << std::endl;
    std::cout << S<int, int, int>().id() << std::endl;
    std::cout << S<int, int, char>().id() << std::endl;
    std::cout << S<char, char, char>().id() << std::endl;
    // 歧义
    //std::cout << S<int, char, char>().id() << std::endl;

    return 0;
    }

    //========================================================
    模板的递归示例

    // 11111.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"
    #include <iostream>
    #include <string>

    template<int i>
    int mult()
    {
    return i * mult<i - 1>();
    }

    template<>
    int mult<1>()
    {
    return 1;
    }

    int main()
    {
    std::cout << "mult<4> = " << mult<4>();
    return 0;
    }

  • 相关阅读:
    Java.io.outputstream.PrintStream:打印流
    Codeforces 732F. Tourist Reform (Tarjan缩点)
    退役了
    POJ 3281 Dining (最大流)
    Light oj 1233
    Light oj 1125
    HDU 5521 Meeting (最短路)
    Light oj 1095
    Light oj 1044
    HDU 3549 Flow Problem (dinic模版 && isap模版)
  • 原文地址:https://www.cnblogs.com/itdef/p/5746058.html
Copyright © 2011-2022 走看看