2017-02-16 13 views
1

Я хотел бы написать функцию шаблона, которая может вызывать функцию с заданными параметрами.Вызвать функцию/функтор с параметрами больше аргументов

Например, можно написать простую функцию: Invoke

template<class F, class... Args> 
inline auto invoke(F &&func, Args&&... args) -> decltype(auto) 
{ 
    return std::forward<F>(func)(std::forward<Args>(args)...); 
} 

Этот invoke принимает тот же счетчик параметра, который требует f. Тем не менее, я хочу, чтобы эта функция шаблона допускала дополнительные неиспользованные параметры. То есть, я хочу, чтобы написать код, как:

auto f = [] (auto a) {...}; 
invoke(f, 1, 2, 3); 

Здесь f принимает только один параметр так, я хочу invoke игнорировать другие параметры, кроме первого. Это может быть достигнуто очень легко, если вы обнаружите арность лямбда, если только лямбда не является общей.

Поскольку f здесь является родовым лямбда, насколько я знаю, нет вообще способ выяснить арность f без явного конкретизации его template operator()<...>.

Как я могу wirete мой invoke?

ответ

4

Одним из возможных вариантов:

#include <utility> 
#include <cstddef> 
#include <tuple> 

template <std::size_t... Is, typename F, typename Tuple> 
auto invoke_impl(int, std::index_sequence<Is...>, F&& func, Tuple&& args) 
    -> decltype(std::forward<F>(func)(std::get<Is>(std::forward<Tuple>(args))...)) 
{ 
    return std::forward<F>(func)(std::get<Is>(std::forward<Tuple>(args))...); 
} 

template <std::size_t... Is, typename F, typename Tuple> 
decltype(auto) invoke_impl(char, std::index_sequence<Is...>, F&& func, Tuple&& args) 
{ 
    return invoke_impl(0 
        , std::index_sequence<Is..., sizeof...(Is)>{} 
        , std::forward<F>(func) 
        , std::forward<Tuple>(args)); 
} 

template <typename F, typename... Args> 
decltype(auto) invoke(F&& func, Args&&... args) 
{ 
    return invoke_impl(0 
        , std::index_sequence<>{} 
        , std::forward<F>(func) 
        , std::forward_as_tuple(std::forward<Args>(args)...)); 
} 

DEMO

+0

Несвязанные: Для вызываемого объекта, это будет иногда вызвать 'оператор()', который имеет наименьшее число параметров. Можно ли назвать лучший матч? – felix

+0

@felix У меня нет идеи atm; возможно, можно наследовать от лямбда-объектов и импортировать их операторов(), но по крайней мере один из них должен принимать все параметры. Я не могу исключить другие возможности. –

+0

О, это всегда впечатляет, чтобы увидеть умный код метапрограммирования шаблонов! Спасибо. – xylosper

 Смежные вопросы

  • Нет связанных вопросов^_^