用可变参数的一部分调用函数 [英] Call function with part of variadic arguments

查看:126
本文介绍了用可变参数的一部分调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一下我的情况:

void bar(int a, int b)
{
}   

template<typename F, typename... Args>
void foo(F function, Args... args>
{
    function(args...);
}

我想以某种方式仅将必要数量的参数传递给函数,这样我就可以执行以下操作,这将导致对以1,作为参数丢弃的bar的调用3.不知道传入的函数类型F需要多少个参数.

I would like to have some kind of way to only pass the necessary amount of arguments to the function, so that I would be able to do the following, which should result in a call to bar with 1, 2 as arguments discarding the 3. Without knowing how many arguments the passed in function type F needs.

foo(bar, 1, 2, 3);
foo([](int a, int b){}, 1, 2, 3);

当我尝试使用以下功能特征时:

When I try to use the below function traits:

namespace detail
{
    template<typename F, std::size_t... Is, class Tup>
    void call_discard_impl(F&& func, std::index_sequence<Is...>, Tup&& tup) 
    {
        std::forward<F>(func)(std::get<Is>(tup)...);
    }
}

template<typename F, typename... Args>
void call_discard(F&& func, Args&&... args)
{
    detail::call_discard_impl(std::forward<F>(func),
        std::make_index_sequence<function_traits<F>::num_args>{},
        std::forward_as_tuple(args...));
}

我得到:

error C2510: 'F': left of '::' must be a class/struct/union
error C2065: '()': undeclared identifier
error C2955: 'function_traits': use of class template requires template argument list

开启:

template <typename F>
struct function_traits : public function_traits<decltype(&F::operator())>
{}

我确实获得了不需要功能特征的成员函数版本:

I did get the member function version working which did not require the function traits:

namespace detail
{
    template<typename O, typename R, typename... FunArgs, std::size_t... Is, class Tup>
    void call_discard_impl(O* obj, R(O::*mem_func)(FunArgs...), std::index_sequence<Is...>, Tup&& tup)
    {
        ((*obj).*mem_func)(std::get<Is>(tup)...);
    }
}

template<typename O, typename R, typename... FunArgs, typename... Args>
void call_discard(O* obj, R(O::*mem_func)(FunArgs...), Args&&... args)
{
    detail::call_discard_impl(obj, mem_func,
        std::make_index_sequence<sizeof...(FunArgs)>{},
        std::forward_as_tuple(args...));
}

推荐答案

首先,我们需要一个函数来检索该函数所需的数字或参数.这是通过 function_traits :

First, we need a function to retrieve the number or arguments the function requires. This is done using function_traits:

template <class F>
constexpr std::size_t nb_args() {
   return utils::function_traits<F>::arity;
}

借助 std::index_sequence 的帮助,我们仅调度nb_args<F>()第一个参数:

template<typename F, std::size_t... Is, class Tup>
void foo_impl(F && f, std::index_sequence<Is...>, Tup && tup) {
    std::forward<F>(f)( std::get<Is>(tup)... );
}

template<typename F, typename... Args>
void foo(F && f, Args&&... args) {
    foo_impl(std::forward<F>(f),
             std::make_index_sequence<nb_args<F>()>{},
             std::forward_as_tuple(args...) );
}

演示

Demo

这篇关于用可变参数的一部分调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆