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();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章