Не особенно креативно, но ...
Если вы создаете функцию foo()
следующим образом
template <typename ... Args>
bool foo (std::tuple<Args...> const & tf)
{ return bar<0>(tf); }
, которая вызывает, начиная с индекса шаблона 0, следующую пару шаблонов (SFINAE включен / отключен) альтернативные функции
template <std::size_t I, typename ... Args>
typename std::enable_if<(I >= sizeof...(Args)), bool>::type
bar (std::tuple<Args...> const &)
{ return false; }
template <std::size_t I, typename ... Args>
typename std::enable_if<(I < sizeof...(Args)), bool>::type
bar (std::tuple<Args...> const & tf)
{ return baz(std::get<I>(tf)) || bar<I+1U>(tf); }
и дополнительная функция baz()
для вызова одиночных функторов
bool baz (functor const & f)
{ return f(); }
Полагаю, вы можете получить то, что хотите.
Ниже приведен полный рабочий пример
#include <tuple>
#include <iostream>
#include <functional>
using functor = std::function<bool()>;
bool baz (functor const & f)
{ return f(); }
template <std::size_t I, typename ... Args>
typename std::enable_if<(I >= sizeof...(Args)), bool>::type
bar (std::tuple<Args...> const &)
{ return false; }
template <std::size_t I, typename ... Args>
typename std::enable_if<(I < sizeof...(Args)), bool>::type
bar (std::tuple<Args...> const & tf)
{ return baz(std::get<I>(tf)) || bar<I+1U>(tf); }
template <typename ... Args>
bool foo (std::tuple<Args...> const & tf)
{ return bar<0>(tf); }
bool f0 () { std::cout << "f0 "; return false; }
bool f1 () { std::cout << "f1 "; return false; }
bool f2 () { std::cout << "f2 "; return false; }
bool f3 () { std::cout << "f3 "; return false; }
bool f4 () { std::cout << "f4 "; return true; }
bool f5 () { std::cout << "f5 "; return false; }
bool f6 () { std::cout << "f6 "; return false; }
bool f7 () { std::cout << "f7 "; return false; }
bool f8 () { std::cout << "f8 "; return false; }
bool f9 () { std::cout << "f9 "; return false; }
int main ()
{
auto tf = std::make_tuple(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
foo(tf);
}
Очевидно, что вы можете избежать использования baz()
и просто вызывать функторы следующим образом
return std::get<I>(tf)() || bar<I+1U>(tf);
, но вы теряете проверкуArgs...
типы.