• C++ 元编程 学习二


    简介

    C++ 元编程 学习之二

    参考资料

    C++ 模板元编程实战

    code

    #include <iostream>
    // 编译器分支与多种返回类型 写法1
    template <bool Check, std::enable_if_t<Check> * = nullptr>
    auto fun(){
        return (int) 0;
    }
    
    template <bool Check, std::enable_if_t<!Check> * = nullptr>
    auto fun() {
        return (double) 1;
    }
    
    template<bool Check>
    auto wrap2() {
        return fun<Check>();
    }
    
    // 编译期分支与多种返回类型  C++17
    template <bool Check>
    auto fun_(){
        if constexpr (Check) { // 编译期接收值,然后构建运行期的函数
            return (int) 0;
        }else {
            return (double) 1;
        }
    }
    
    // 循环代码实现  使用递归实现
    template <size_t Input>
    constexpr size_t OnesCount = (Input % 2) + OnesCount<(Input / 2)>;
    // 终止递归
    template<> constexpr size_t OnesCount<0> = 0;
    
    // 循环代码实现 对于数组求和
    template <size_t...Inputs>
    constexpr size_t Accumulate = 0;
    
    template<size_t CurInput, size_t ...Inputs>
    constexpr size_t Accumulate <CurInput, Inputs...> = CurInput + Accumulate<Inputs...>;
    
    // C++ 17 实现技术
    template<size_t... values>
    constexpr size_t fun_1(){
        return (0 + ... + values);
    }
    
    // 容易实例爆炸
    // template <size_t A>
    // struct Wrap_{
    //     template <size_t ID, typename TDummy = void>
    //     struct imp {
    //         constexpr static size_t value = ID + imp<ID - 1>::value;
    //     };
    
    //     template <typename TDummy>
    //     struct imp<0, TDummy> {
    //         constexpr static size_t value = 0;
    //     };
    
    //     template <size_t ID>
    //     constexpr static size_t value = imp<A + ID>::value;
    // };
    
    // 不容易实例爆炸的样例  公用了 imp的实现
    template <size_t ID>
    struct imp {
        constexpr static size_t value = ID + imp<ID - 1>::value;
    };
    
    template<>
    struct imp<0> {
        constexpr static size_t value = 0;
    };
    
    template <size_t A>
    struct Wrap_{
        template <size_t ID>
        constexpr static size_t value = imp<A + ID>::value;
    };
    
    // 短路逻辑未实现的版本  判断是否全是素数
    /*
    template <size_t N>
    constexpr bool is_odd = ((N % 2) == 1);
    
    template <size_t N>
    struct AllOdd_ {
        constexpr static bool is_cur_odd = is_odd<N>;
        constexpr static bool is_pre_odd = AllOdd_<N - 1>::value;
        constexpr static bool value = is_cur_odd && is_pre_odd;
    };
    
    template <>
    struct AllOdd_<0> {
        constexpr static bool value = is_odd<0>;
    };
    */
    
    template <size_t N>
    constexpr bool is_odd = ((N % 2) == 1);
    
    template <bool cur, typename TNext>
    constexpr static bool AndValue = false;
    
    template <typename TNext>
    constexpr static bool AndValue<true, TNext> = TNext::value;
    
    template<size_t N>
    struct AllOdd_ {
        constexpr static bool is_cur_odd = is_odd<N>;
        constexpr static bool value = AndValue<is_cur_odd, AllOdd_<N - 1>>;
    };
    
    template <>
    struct AllOdd_<0> {
        constexpr static bool value = is_odd<0>;
    };
    
    // 构建虚函数 通过CRTP
    template<typename D>
    struct Base{
        template <typename TI>
        void Fun(const TI&input){
            D* ptr = static_cast<D*>(this);
            ptr->Imp(input);
        }
    };
    
    struct Derive : public Base<Derive>{
        template <typename TI>
        void Imp(const TI& input){
            std::cout << input << std::endl;
        }
    };
    
    // 类的静态函数被声明为虚函数?QU:什么鬼
    template <typename D>
    struct Base1{
        static void Fun(){
            D::Imp();
        }
    };
    
    struct Derive1: public Base1<Derive1>{
        static void Imp(){
            std::cout << "Implementation from derive class11" << std::endl;        
        }
    };
    
    
    
    
    #include "header1.hh"
    using namespace std;
    int main() {
        cerr << wrap2<true>() << std::endl;
        cerr << wrap2<false>() << std::endl;
    
        std::cerr << fun_<true>() << std::endl;
    
        constexpr size_t res = OnesCount<45>;
        std::cerr << res << std::endl;
    
        constexpr size_t res1 = Accumulate<1, 2, 3, 4, 5>;
        std::cerr << res1 << std::endl;
    
        constexpr size_t res2 = fun_1<1,2,3,4,5>();
        std::cerr << res2 << std::endl;
    
        std::cerr << Wrap_<3>::value<2> << std::endl;
        std::cerr << Wrap_<10>::value<2> << std::endl;
    
        Derive d;
        d.Fun("Implementation from derive class");
    
        Derive1::Fun();
    }
    
  • 相关阅读:
    利用jmeter进行数据库测试
    oracle创建/删除表空间、创建/删除用户并赋予权限
    在linux环境下安装JDK并配置环境变量
    本地与在线图片转Base64及图片预览
    html标签页图标
    Eclipse启动时卡死解决方法
    Java创建目录 mkdir与mkdirs的区别
    Java 获取距离最近一段时间的时间点
    data URI
    JavaScript input file上传前获取文件名、文件类型、文件大小等信息
  • 原文地址:https://www.cnblogs.com/eat-too-much/p/14325390.html
Copyright © 2020-2023  润新知