我想编写一个模板函数,它可以调用给定参数的函数。
例如,我可以编写一个简单的调用函数:
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是通用的,否则这可以通过获得lambda的arity来轻松实现。
由于f
这里是通用lambda,据我所知,没有一般方法可以在没有明确实例化f
的情况下找出template operator()<...>
的arity。
我怎样才能找到invoke
?
答案 0 :(得分: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)...));
}