引数の型だけ違う関数オブジェクトの処理をtemplateで切り分ける−2
記事のまとめ
続いたのでまとめておく。
本文
をもうちょっとtraits使ってるぽく書いた例。結果は同じなので省略。std::conditionalとfunction traitsつかえばもうちょい綺麗になりそう。
#include <iostream> #include <vector> //1引数をとるメンバ関数用のテンプレート&Arg_の型で処理を切り分け namespace moge_traits { //vector/doubleを切り分けるタグ struct tagV{}; struct tagD{}; //適当なクラスメソッド型 template <typename T_, typename Arg_> struct ClassMethod{ typedef void (T_::*type)(Arg_); }; //moge_traitsで処理切り分け用tagのtypedef template<typename T_, typename ClassMethod_> struct traits { typedef tagV tag; }; template<typename T_> struct traits<T_, typename ClassMethod<T_, double>::type>{ typedef tagD tag; }; //API template<typename T_> void operatorInner(T_ t, std::vector<double> x){ detail::operatorInner(t, x, traits<T_, decltype(&T_::operator())>::tag());} namespace detail { //タグに応じた実際の処理 template<typename T_> void operatorInner(T_ t, std::vector<double> x, tagV){ t(x); } template<typename T_> void operatorInner(T_ t, std::vector<double> x, tagD){ t(x[0]); } } } //引数の型が違うクラス struct A{ void operator()(double x){ std::cout << "I'm class A:" << x << std::endl; } }; struct B{ void operator()(std::vector<double> x){ std::cout << "I'm class B:" << x[0] << ", " << x[1] << ", " << x[2] << std::endl; } }; //中でA・Bクラスを使う適当なクラス template<typename T_> struct Moge { Moge(T_ x) : x_(x){} void operator()(std::vector<double> x){ moge_traits::operatorInner(x_, x); } T_ x_; }; //メイン int main() { std::vector<double> xxx = { 1, 2, 3 }; B b; Moge<B> x1(b); x1(xxx); A a; Moge<A> x2(a); x2(xxx); return 0; }