如何从函数指针推导参数列表? [英] How to Deduce Argument List from Function Pointer?

查看:74
本文介绍了如何从函数指针推导参数列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定两个或更多示例函数,是否可以编写模板代码以推断出作为模板参数提供的函数的自变量?

Given two or more example functions, is it possible to write templated code which would be able to deduce the arguments of a function provided as a template parameter?

这是很有启发性的例子:

This is the motivating example:

void do_something(int value, double amount) {
    std::cout << (value * amount) << std::endl;
}

void do_something_else(std::string const& first, double & second, int third) {
    for(char c : first) 
        if(third / c == 0) 
            second += 13.7;
}

template<void(*Func)(/*???*/)>
struct wrapper {
    using Args = /*???*/;
    void operator()(Args&& ... args) const {
        Func(std::forward<Args>(args)...);
    }
};

int main() {
    wrapper<do_something> obj; //Should be able to deduce Args to be [int, double]
    obj(5, 17.4); //Would call do_something(5, 17.4);
    wrapper<do_something_else> obj2; //Should be able to deduce Args to be [std::string const&, double&, int]
    double value = 5;
    obj2("Hello there!", value, 70); //Would call do_something_else("Hello there!", value, 70);
}

/* ??? */的两种用法中,我都在尝试找出可以放置这种代码的地方.

In both uses of /*???*/, I am trying to work out what I could put there that would enable this kind of code.

以下内容似乎无效,这是因为 Args 在首次使用之前未定义(此外,我不得不假设还有许多语法错误),即使这样做,我仍在寻找不需要显式编写类型的版本:

The following doesn't appear to work, due to Args not being defined before its first use (along with what I have to assume are numerous syntax errors besides), and even if it did, I'm still looking for a version that doesn't require explicit writing of the types themselves:

template<void(*Func)(Args ...), typename ... Args)
struct wrapper {
    void operator()(Args ...args) const {
        Func(std::forward<Args>(args)...);
    }
};

wrapper<do_something, int, double> obj;

推荐答案

使用C ++ 17,我们可以使用自动模板非类型参数,从而使 Wrapper< do_something>w {} 语法 1).

With C++17 we can have auto template non-type parameters which make possible the Wrapper<do_something> w{} syntax 1).

要推断出 Args ... ,您可以使用专业化来做到这一点./p>

As for deducing Args... you can do that with a specialization.

template <auto* F>
struct Wrapper {};

template <class Ret, class... Args, auto (*F)(Args...) -> Ret>
struct Wrapper<F>
{
    auto operator()(Args... args) const
    {
        return F(args...);
    }
};

Wrapper<do_something> w{};
w(10, 11.11);


1)如果没有C ++ 17,就不可能有 Wrapper< do_something>w {} 不错的语法.


1) Without C++17 it's impossible to have the Wrapper<do_something> w{} nice syntax.

您能做的最好的事情是:

The best you can do is:

template <class F, F* func>
struct Wrapper {};

template <class Ret, class... Args, auto (*F)(Args...) -> Ret>
struct Wrapper<Ret (Args...), F>
{
    auto operator()(Args... args) const
    {
        return F(args...);
    }
};

Wrapper<declype(do_something), do_something> w{};

这篇关于如何从函数指针推导参数列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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