1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
#include <iostream>
#include <tuple>
#include <utility>
struct Otherwise { // ***
Otherwise(...) {} // Any value passed in the last argument of test_impl can be (implicitly) converted to an Otherwise object.
};
template <typename Tuple, std::size_t... Is, typename F, typename = decltype(std::declval<F>()(std::get<Is>(std::declval<Tuple>())...))>
void test_impl (const Tuple&, const std::index_sequence<Is...>&, F, int) {
std::cout << sizeof...(Is) << " arguments needed.\n";
}
template <typename Tuple, std::size_t... Is, typename F>
void test_impl (const Tuple& tuple, const std::index_sequence<Is...>&, F f, Otherwise) {
// std::cout << "More than " << sizeof...(Is) << " arguments needed.\n";
test_impl (tuple, std::index_sequence<Is..., sizeof...(Is)>{}, f, 0); // *** Pass an integer, e.g. 0.
}
template <typename Tuple, typename F>
void test (const Tuple& tuple, F f) {
test_impl(tuple, std::index_sequence<0>{}, f, 0);
}
void foo (int, char, bool) {}
int main() {
const auto tuple = std::make_tuple(5, 'a', true, 3.5);
test (tuple, foo); // 3 arguments needed.
}
|