2017-02-16 116 views
1

我想编写一个模板函数,它可以调用具有给定参数的函数。调用参数多于参数的函数/仿函数

例如,我可以写一个简单的调用函数:

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忽略除了第一个其他参数。 这可以很容易地通过获得lambda的arity来实现,除非lambda是通用的。

由于f这里是通用lambda,据我所知,没有通用的方法来找出它的f的arity没有明确实例化其template operator()<...>

我该如何保护我的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;也许可以从lambda对象继承并导入它们的操作符(),但至少其中一个应该接受所有参数。我不能排除其他可能性。 –

+0

哦,看到聪明的模板元编程代码总是令人印象深刻!谢谢。 – xylosper