引数の型だけ違う関数オブジェクトの処理を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;
}