Я пытаюсь автоматизировать создание функций для выполнения параметризации и распределения результатов в / из функций обратного вызова на основе вариантов.Конечная цель - облегчить интеграцию обратных вызовов к одному или нескольким языкам сценариев (возможно, JavaScript и / или Lua).
Я новичок в метапрограммировании шаблонов C ++ (и SO), поэтому я уверен, чтоЯ сделал кучу ошибок новичка в моем подходе.Вот что у меня есть ...
namespace mpl = boost::mpl;
namespace ft = boost::function_types;
namespace fusion = boost::fusion;
typedef boost::variant<boost::none_t, bool, int, double, std::wstring> Variant;
typedef std::vector<Variant> VariantList;
template < typename T >
VariantList AppendVariantToList(VariantList list, const T &t)
{
list.push_back(t);
return list;
}
template < typename T >
T get(Variant &v)
{
return boost::get<T>(v);
}
typedef Variant callback_type(const VariantList &);
Variant InvokeCallback(const VariantList &args)
{
// This method will eventually invoke the actual script callback.
return true;
}
template < typename Function
, class From = typename mpl::begin<ft::parameter_types<Function>>::type
, class To = typename mpl::end<ft::parameter_types<Function>>::type
>
struct callback_binder
{
typedef typename mpl::deref<From>::type arg_type;
typedef typename mpl::next<From>::type next_iter_type;
template < int n >
static auto apply() -> decltype(boost::bind(AppendVariantToList<arg_type>, callback_binder<Function, next_iter_type, To>::apply<n + 1>(), boost::arg<n>()))
{
return boost::bind(AppendVariantToList<arg_type>, callback_binder<Function, next_iter_type, To>::apply<n + 1>(), boost::arg<n>());
}
static boost::function<Function> apply_1st(callback_type callback)
{
return boost::bind(get<bool>, boost::bind(callback, callback_binder<Function, From, To>::apply<1>()));
}
};
template < typename Function, class To >
struct callback_binder < Function, To, To >
{
template < int n >
static auto apply() -> decltype(boost::bind(boost::value_factory<VariantList>()))
{
return boost::bind(boost::value_factory<VariantList>());
}
};
template < typename Function >
boost::function<Function> make_callback(callback_type callback)
{
return callback_binder<Function>::apply_1st(callback);
}
bool OnSomeEvent(int a, int b)
{
const static auto callback(make_callback<BOOST_TYPEOF(OnSomeEvent)>(InvokeCallback));
return callback(a, b);
}
InvokeCallback
представляет функцию, которая в конечном итоге вызовет функцию языка сценариев.OnSomeEvent
- это пример того места, где я хочу вызвать функцию обратного вызова скрипта.Идея состоит в том, что методы callback_binder::apply
повторяют типы параметров OnSomeEvent
и создают функтор, который заполняет VariantList
, вызывает InvokeCallback
и возвращает результат.
Кажется, что все работает доЯ ввел параметр шаблона < int n >
в методы apply
, чтобы я мог выполнить итерацию boost::args
.К сожалению, попытка скомпилировать приведенный выше код приводит к сбою MS VC ++ 2010 RTM, поэтому я застрял в том, что делать дальше.
РЕДАКТИРОВАТЬ: возможно, конкретный вопрос, который я задаю, - «как мне получить доступ к boost::bind
заполнители в 'metaloop', который я использую выше? "
Спасибо
Simon