Я пишу небольшую оболочку для нашего API, и я столкнулся с проблемой. Каждый вызов от внешнего клиента (механизм JavaScript) выполняется при вызове функции из ApiBase с именем execute, все параметры передаются как std :: string, no mather, что было передано в вызове 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 O 10 параметров строки (всегда 4 или 10), не Mather сколько параметров, где проходил в апи вызова (не спрашивайте меня, почему ...).
Я знаю, что это можно сделать с помощью вариативных шаблонов, но, к сожалению, я не могу использовать его в этом проекте. Мое решение основано на «моделировании вариативных шаблонов», но это просто уродливо. Чтобы поддерживать 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