c++ - 如何从函数指针推导出参数列表?

标签 c++ templates template-meta-programming

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

这是激励人心的例子:

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);
}

/*???*/ 的两种使用中,我都在尝试弄清楚我可以放什么来启用这种代码。

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

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).

至于推导Args...你可以用 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{}漂亮的语法。

你能做的最好的事情是:

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{};

关于c++ - 如何从函数指针推导出参数列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46533698/

相关文章:

c++ - 为什么我不能创建带有可选 UnaryPredicate 参数的模板函数?

c++ - 有效地获取参数包的大小达到某个索引

compiler-construction - C++0x TMP编译速度

c++ - 统一2字节为Int

c++ - 如何在 C++ 中将 std::decimal::decimal128 转换为字符串

C++ 输入输出排序

c++ - 扩展包含 int 包的类型

c++ - 免费(): double free detected in tcache 2 in C++

c++ - Qt中的模板问题

c++ - 接受类型对象和所有派生类型对象的模板函数