У меня нет компилятора для тестирования всего этого, поэтому вам придется сообщать о любых проблемах.
Следующее должно позволить вам выполнять итерации по кортежу, вызывающему функцию.Это основано на вашей логике, с небольшими изменениями.(N
- это std::size_t
, это первый параметр, который позволяет выводить Args
(и Func
) при последующих вызовах, он просто вызывает некоторую функцию вместо выполнения определенной задачи).Ничего особенного:
namespace detail
{
// just to keep things concise and readable
#define ENABLE_IF(x) typename std::enable_if<(x)>::type
// recursive case
template <std::size_t N, typename... Args, typename Func>
ENABLE_IF(N >= 1) iterate(const std::tuple<Args...>& pTuple, Func& pFunc)
{
pFunc(std::get<N - 1>(pTuple));
iterate<N - 1>(pTuple, pFunc);
}
// base case
template <std::size_t N, typename... Args, typename Func>
ENABLE_IF(N == 0) iterate(const std::tuple<Args...>&, Func&)
{
// done
}
}
// iterate tuple
template <typename... Args, typename Func>
Func iterate(const std::tuple<Args...>& pTuple, Func pFunc)
{
detail::iterate<sizeof...(Args)>(pTuple, pFunc);
return pFunc;
}
Если предположить, что все работает, то у вас просто есть:
struct push_lua_stack
{
// constructor taking reference to stack to push onto
// initialize count to 0, etc....
template <typename T>
void operator()(const T& pX)
{
// push pX onto lua stack
++count;
}
std::size_t count;
};
И наконец:
std::size_t pushCount = iterate(someTuple, push_lua_stack()).count;
Дайте мне знать, если это всеимеет смысл.
Поскольку по какой-то причине вы действительно серьезно относитесь к структурам, просто создайте такую функцию:
template <typename T>
void push_lua(const T& pX)
{
// push pX onto lua stack
}
И измените все, чтобы вызывать эту функцию специально:
namespace detail
{
// just to keep things concise and readable
#define ENABLE_IF(x) std::enable_if<(x)>::type* = nullptr
// recursive case
template <std::size_t N, typename... Args>
typename ENABLE_IF(N >= 1) iterate(const std::tuple<Args...>& pTuple)
{
// specific function instead of generic function
push_lua(std::get<N - 1>(pTuple));
iterate<N - 1>(pTuple);
}
// base case
template <std::size_t N, typename... Args, typename Func>
typename ENABLE_IF(N == 0) iterate(const std::tuple<Args...>&, Func&)
{
// done
}
}
// iterate tuple
template <typename... Args>
void _push(const std::tuple<Args...>& pTuple)
{
detail::iterate<sizeof...(Args)>(pTuple);
}
Не знаю, почему бы вам избежать универсальной функциональности или быть против структур.
О, как бы хороши были полиморфные лямбды.Отбросьте утилиту push_lua_stack
класса и просто напишите:
std::size_t count = 0;
iterate(someTuple, [&](auto pX)
{
// push onto lua stack
++count;
});
Ну да ладно.