Variadic Templateの(僕が今更ながら新しく知った)使い方
知った事など
- 継承させる
struct Base1{}; struct Base2{}; // すべての型引数を継承 template<typename... Args> struct Derived : Args... { int a; }; int main(){ Derived<Base1,Base2> a; }
- mapして包含する(直接保持は無理)
struct Base1{}; struct Base2{}; template<typename... Ts> struct holder { }; template<typename T> struct Map { }; // template<typename... Args> struct Derived { // 保持 typedef holder< Args... > hold_; // ERROR //typedef Map<Args...> type; // Args...をMapにmap // そのままは持てないのでラップする typedef holder< Map<Args>... > type; }; int main(){ Derived<Base1,Base2> a; }
- mapして継承させる
struct Base1{}; struct Base2{}; template<typename T> struct Map { }; // 継承 tempalte<typename... Args> struct Derived : Map<Args>... { }; int main(){ Derived<Base1,Base2> a; }
- もちろん複数のVaridic templateでも可
struct Base1{}; struct Base2{}; template<int N,typename T> struct Map { }; // 継承 tempalte<int...Ns, typename... Args> struct Derived : Map<Ns,Args>... { }; int main(){ Derived<1,2,Base1,Base2> a; }
- 継承させた値(value)を扱う
// Argsの一部 struct Base1{ int value_; }; // Argsの一部 struct Base2{ int value_; }; // 継承 tempalte<typename... Args> struct Derived : Args... { template<typename T> auto get(T& t) { return t.value; } }; int main() { Derived<Base1,Base2> a(); a.get<Base1>(); //Base1.value_ }
通常であれば、valueはBase1::valueとBase2::valueの2つあって区別できないのですが
get関数内でthisを継承元にキャストすることで、Base1の持つ変数、関数を直接操作することが可能になっています
(多重継承の場合は使えるのかな?)
本題
と言う事で、Map<N,T>を適応しつつ複数の型を継承することで
面白い事ができるようです
template<int N,typename T> struct Map { T value_; }; // 継承 tempalte<int... Ns, typename... Args> struct Derived : Map<N,Args>... { tempalte<int N> auto get() { return get_<N>(*this); } // 今回this(Derived型)はMap<1,int>,Map<2,double>,Map<3,char>を継承する // するとget_<1>のようにして数字を与えthisを引数にとると // どのMap<1,T>のT(即ちint)をthisの継承一覧から推論してくれる template<int N, typename T> static auto get_(Map<N,T>& t) { return t.value; } }; int main() { Derived<1,2,3,int,double,char> a(); a.get<1>(); // return int a.get<2>(); // return double a.get<3>(); // return char }
おもしろいですね
「Map<T,N>のどちらか一方が判明しているのなら、もう一方を推論できる」
のような挙動をしています
上のコードではget
Map<N,T>の第2型引数であるTを推論しています
とてもおもしろいです。私ははじめて知りました
tuple
面白半分でtupleを実装してみました
数字を自動生成してはいるものの、
いわゆるO(n)オーダーというナンセンスな実装です
http://melpon.org/wandbox/permlink/lTybRjzNIs0iNcSt