• C++模板元编程


    这个还是基于之前实现的那个MultiState,为了实现三种类型“大类”的函数重载决议:所有整数、所有浮点数、字符串,分别将这三种“大类”的数据分配到对应的Converter上。

    为此实现了一些方便的类型运算工厂,比如TypeEqFact,同于生成比较两个类型是否相等的谓词,PredOrFact,用于生成将若干个谓词采用“或”运算生成的新谓词。

    template<class T>
    struct TypeEqFact
    {
        template<class TTest>
        using Get = typename TypeEq<T, TTest>;
    };

    template<template<class T> class... TPreds>
    struct PredOrFact
    {
        template<class TStatement>
        using Get = typename TypeNeq<
            typename MultiState<TStatement, TPreds...>::Result,
            FalseType
        >;
    };

    这里就形成了我自己模板元编程里的另一个约定,工厂模板使用Get成员获取产生的模板谓词

    使用起来就是这样的

    TypeEqFact<char*>::Get

    这个东西就是一个谓词了,就是一个模板类,就像没有加尖括号的vector那样,不能直接定义类型,如果给它一个实例类,像 TypeEqFact<char*>::Get<int>::Result x; ,这里面x的类型就是FalseType; TypeEqFact<char*>::Get<char*>::Result y; ,这里面y就是TrueType。

    至于PredOrFact,这样用:

    PredOrFact<IsInteger, IsFloat>::Get

    这个东西也是一个谓词,正常使用就好,比如

    PredOrFact<IsInteger, IsFloat>::Get<int>::Result x1;
    PredOrFact<IsInteger, IsFloat>::Get<long>::Result x2;
    PredOrFact<IsInteger, IsFloat>::Get<float>::Resukt x3;
    PredOrFact<IsInteger, IsFloat>::Get<long double>::Result x4;

    这里面x1~x4都是TrueType,因为他们满足这里面两个谓词中的其中一个,而对于其他的既不是正数又不是浮点数的类型,他们的结果都是FalseType。

    合并起来,在我的类型重载决议代码里:

    MultiState<TNumber, IsInteger, IsFloat, PredOrFact<TypeEqFact<char*>::Get, TypeEqFact<const char*>::Get>::Get>::Result();

    太乱了?这么看

    MultiState<
        TNumber,
        IsInteger,
        IsFloat,
        PredOrFact<
            TypeEqFact<char*>::Get,
            TypeEqFact<const char*>::Get
        >::Get
    >::Result();

    MultiState接受一个TNumber,把它依序和三个谓词进行比较,前两个是自带的谓词,第三个是用PredOrFact工厂生成的,被合成的两个谓词,分别是用TypeEqFact工厂生成的。

    这样最后的结果,所有的整数使用一个函数,所有的浮点数使用一个函数,所有的字符串(char*,const char*)使用一个函数,只要写三个,还不需要模板特例化什么的。

    函数的类型参数里只要分别给每一个类型大类写一个仅用于重在决议的类型参数就好,像这样:

    template<typename T>
    static std::vector<bool> ToVectorBool(T intNumber, State<0>);
    template<typename T>
    static std::vector<bool> ToVectorBool(T floatNumber, State<1>);
    template<typename T>
    static std::vector<bool> ToVectorBool(T cstrNumber, State<2>);

    State<0>~State<2>分别对应上面那行代码生成的类型。

    爽。

  • 相关阅读:
    js全局变量
    $.getJSON异步请求和同步请求
    让js中的函数只有一次有效调用
    两个div并排显示,当浏览器界面缩小时会出现换行
    jquery获取窗口和文档的高度和宽度
    后台传带引号(")的数据需要注意
    C# dynamic
    (转)数据库函数解析JSON字符串
    Unicode和UTF-8
    用户通过浏览器修改表单隐藏域
  • 原文地址:https://www.cnblogs.com/pointer-smq/p/4999298.html
Copyright © 2020-2023  润新知