簡介
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();
}