当前位置: 首页 > 知识库问答 >
问题:

变分高阶函数的过载解析

糜俊彦
2023-03-14

假设我有一个变量高阶函数

template<typename F, typename ...Args>
void execution(F func, Args&&... args)
{
    func(std::forward<Args>(args)...);
}

那么对于这个过载集

void f() {}
void f(int arg) {}

过载解决将是不可能的

int main()
{
    execution(f, 1);
    execution(f);
    return 0;
}

然而,如果只提供两者中的任何一个,程序就会编译

>

  • 为什么会发生这种情况?为什么模板参数演绎失败?
  • 如果我从集合中删除f()并将其替换为f(arg,arg2),仍然存在问题。是否有解决方法,或者我是否始终必须提供函数的类型作为模板参数?

    execution<void()>(f);
    
  • 共有3个答案

    冀永寿
    2023-03-14

    没有可用的特定函数“f ”:

    简化它:

    template<typename F>
    void execution(F func)
    {}
    
    void f() {}
    void f(int arg) {}
    
    int main()
    {
        execution(f);
        return 0;
    }
    

    您有两个函数'f'可用于模板参数推导/替换

    井斌斌
    2023-03-14

    您需要一个重载集对象。这是一个表示f的整个重载函数集的对象:

    struct f_overload_set {
      template<typename...As>
      auto operator()(As&&...as)->
        decltype(f(std::declval<As>()...))
      { return f(std::forward<As>(as)...); }
    };
    

    现在将f_overload_set{}传递给您的模板函数。

    模板函数值参数必须是值,并且在当前C中没有代表函数的整个重载集的第一类值。符号f在每个使用点被消歧为一个重载:但这需要在使用点的即时上下文。上面推迟了消歧,直到我们有了可用的参数。

    国高杰
    2023-03-14

    在进行模板类型推导时,编译器不会分析函数内部如何使用类型。因此,在推导模板参数时,编译器看不到不同模板参数之间的关系。因此,额外的可变参数模板参数根本无关紧要,问题可以简化为

    template<typename Func> void execution(Func func);
    
    void f();
    void f(int);
    
    execution(f);
    

    有了这个最小化的代码,模板参数推导失败的原因应该很明显。

    您可以通过使第一个参数显式依赖于其余模板参数来解决此问题,例如:

    template<typename... Args>
     void execution(void (*func)(Args ...), Args ... args)
    {
      func(std::forward<Args>(args) ...);
    }
    
     类似资料:
    • Haskell 中的函数可以接受函数作为参数也可以返回函数作为结果,这样的函数就被称作高阶函数。高阶函数可不只是某简单特性而已,它贯穿于 Haskell 的方方面面。要拒绝循环与状态的改变而通过定义问题"是什么"来解决问题,高阶函数必不可少。它们是编码的得力工具。 Curried functions 本质上,Haskell 的所有函数都只有一个参数,那么我们先前编那么多含有多个参数的函数又是怎么回

    • 简介 高阶函数(Higher Order Function)是一种以函数为参数的函数。它们都被用于映射(mapping)、过滤(filtering)、归档(folding)和排序(sorting)表。高阶函数提高了程序的模块性。编写对各种情况都适用的高阶函数与为单一情况编写递归函数相比,可以使程序更具可读性。比如说,使用一个高阶函数来实现排序可以使得我们使用不同的条件来排序,这就将排序条件和排序过

    • 高阶函数英文叫Higher-order function。那么什么是高阶函数? JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。 一个最简单的高阶函数: function add(x, y, f) { return f(x) + f(y); } 当我们调用add(-5, 6, M

    • 高阶函数英文叫Higher-order function。什么是高阶函数?我们以实际代码为例子,一步一步深入概念。 变量可以指向函数 以Python内置的求绝对值的函数abs()为例,调用该函数用以下代码: >>> abs(-10) 10 但是,如果只写abs呢? >>> abs <built-in function abs> 可见,abs(-10)是函数调用,而abs是函数本身。 要获得函数

    • 高阶函数英文叫Higher-order function。什么是高阶函数?我们以实际代码为例子,一步一步深入概念。 变量可以指向函数 以Python内置的求绝对值的函数abs()为例,调用该函数用以下代码: >>> abs(-10) 10 但是,如果只写abs呢? >>> abs <built-in function abs> 可见,abs(-10)是函数调用,而abs是函数本身。 要获得函数

    • Rust 提供了高阶函数(Higher Order Function, HOF)。执行一个或多个函数来产生一个用处更大的函数。HOF 和惰性迭代器(lazy iterator)给 Rust 带来了函数式的风格(英文原文:HOFs and lazy iterators give Rust its functional flavor.)。 fn is_odd(n: u32) -> bool {