Я хочу включить luabind
в один из моих проектов. Для этого мне нужно предоставить функцию, которая ведет себя аналогично call_function
(см. ниже). Эта функция использует некоторую магию шаблонов (любезно предоставленную Boost), с которой я был бы признателен за помощь. Это первый раз, когда я действительно столкнулся с метапрограммированием шаблонов (это так называется?), и поэтому я немного растерялся. Вот несколько фрагментов, с которыми я был бы признателен за помощь.
#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
Я не совсем уверен, что делает этот бит препроцессора, я даже не знаю, как он называется, поэтому поиск немного затруднен. A
— это тип шаблона. Если я правильно помню, #a
будет вставлять буквальный текст a
, но что делают кратные #
? После этого препроцессора идет вот это.
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
call_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
{
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
#if BOOST_PP_ITERATION() == 0
tuple_t args;
#else
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
#endif
}
Как видите, он интенсивно использует Boost. Я гуглил BOOST_PP_ITERATION
, но до сих пор не могу понять, что он делает. Может кто-нибудь объяснить мне, желательно в контексте этого кода, что делает материал BOOST_PP
и как ему удается получить аргументы в args
.
Моя конечная цель — определить call_function
в моем собственном коде, который будет генерировать args
, который я могу передать перегрузке call_function
, которую я определю. Это означает, что я могу использовать то же соглашение о вызовах, но также могу применить некоторую предварительную обработку перед вызовом luabind
.
Этот вопрос довольно специфичен в том виде, в котором я его сформулировал, но я надеюсь, что концепции достаточно общие, чтобы здесь все было в порядке.