zoukankan      html  css  js  c++  java
  • 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>分别对应上面那行代码生成的类型。

    爽。

  • 相关阅读:
    STL map与Boost unordered_map
    static constructors in C++? need to initialize private static objects
    谈谈C++继承中的重载,覆盖和隐藏
    C++继承:公有,私有,保护
    C++ using关键字作用总结
    ++iter的效率比iter++的效率高
    C++中dynamic_cast,static_cast,const_cast,reinterpret_cast
    【转】WinForm中添加闪屏窗口的两种方法
    【转】一个不错的Matlab的gui界面设计实例 (20081003 15:47:30)matlab gui 界面 校园 分类:Matlab实例
    制作一个WinForm的闪屏
  • 原文地址:https://www.cnblogs.com/pointer-smq/p/4999298.html
Copyright © 2011-2022 走看看