我正在爲我們的API編寫一個小包裝,並且遇到了問題。 每個來自外部客戶端(JavaScript引擎)的調用都是由ApiBase命名的execute調用函數完成的,所有參數都以std :: string的形式傳遞,而不是通過api調用傳遞的參數,每個值都被轉換爲字符串。模擬可變模板
我的想法是使用指向成員函數的指針,並嘗試將那些傳遞的字符串轉換爲正在寫入特定函數的程序員所需的C++類型。
例如:
struct MyApiForVeryImportantDevice{
void Init(int, int);
};
MyApiForVeryImportantDevice api_entry;
ApiBase* api = make_api(&api_entry, &MyApiForVeryImportantDevice::Init);
//serve api
Somwhere代碼api->execute("1", "2", "", "")
被調用4點10個字符串參數(總是4或10),無馬瑟多少參數,其中,在API調用傳遞(不要問我爲什麼...)。
我知道這可以用variadic模板完成,但不幸的是我不能在這個項目中使用它。 我的解決方案是基於「模擬variadic模板」,但它只是醜陋的。爲了支持10個參數,我需要編寫10個類ApiCall和10個make_api函數,這很容易出錯,你還有其他想法嗎?某種mpl(可能是類型列表?)? 下面給出的代碼只是2和10參數的例子,我需要類似0-10參數的例子。
問候。
template<class T>
T convert(const string& v){
return T();
}
template<>
int convert(const string& v)
{
return boost::lexical_cast<int>(v);
}
template<class T, class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
class ApiCall : public ApiBase
{
typedef T result_type;
typedef R class_type;
typedef boost::function<result_type(class_type*,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9)> functor_type;
ApiCall(T* obj, functor_type f)
{
func = boost::bind(f, _1, obj);
}
virtual void execute(const string& param1, const string& param2, const string& param3, const string& param4)
{
func(convert<A0>(param0), convert<A1>(param1), convert<A2>(param2), convert<A3>(param3), convert<A4>(param4));
}
virtual void execute(const string& param0, const string& param1, const string& param2, const string& param3,
const string& param4, const string& param5, const string& param6, const string& param7
const string& param8, const string& param9)
{
func(convert<A0>(param0), convert<A1>(param1), convert<A2>(param2), convert<A3>(param3), convert<A4>(param4), convert<A5>(param5),
convert<A6>(param6),convert<A7>(param7), convert<A8>(param8), convert<A9>(param9));
}
private:
functor_type func;
};
template<class T, class R, class A0, class A1>
class ApiCall : public ApiBase
{
typedef R result_type;
typedef T class_type;
typedef boost::function<result_type(class_type*,A0, A1)> functor_type;
ApiCall(T* obj, functor_type f)
{
func = boost::bind(f, _1, obj);
}
virtual void execute(const string& param1, const string& param2, const string& param3, const string& param4)
{
func(convert<A0>(param0), convert<A1>(param1));
}
virtual void execute(const string& param0, const string& param1, const string& param2, const string& param3,
const string& param4, const string& param5, const string& param6, const string& param7
const string& param8, const string& param9)
{
func(convert<A0>(param0), convert<A1>(param1));
}
private:
functor_type func;
};
template<class T, class R, class A0, class A1>
ApiCall<T, R, A0, A1>* make_api(T obj, R(T::*fun)(A0, A1))
{
return new ApiCall<T,R,A0,A!>(obj, fun);
}
template<class T, class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
ApiCall<T,R,A0,A1,A2,A3,A4,A5,A6,A7,A8, A9>* make_api(T obj, R(T::*fun)(A0))
{
return new ApiCall<T,R,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9>(obj, fun);
}
你知道類型列表嗎?看到這裏:http://stackoverflow.com/questions/901907/how-to-use-typelists – LukeCodeBaker