C++ C++;函子优势-保持状态

C++ C++;函子优势-保持状态,c++,functor,C++,Functor,我确实研究了函子的整个概念,不幸的是,我不能理解函子相对于典型函数的真正优势 根据一些学术脚本,函子可以持有不同于函数的状态。 有人能用一些简单易懂的例子来详细说明这一点吗 我真的不明白为什么典型的、常规的函数不能做同样的事情。对于这种新手问题,我真的很抱歉

我确实研究了函子的整个概念,不幸的是,我不能理解函子相对于典型函数的真正优势

根据一些学术脚本,函子可以持有不同于函数的状态。 有人能用一些简单易懂的例子来详细说明这一点吗


我真的不明白为什么典型的、常规的函数不能做同样的事情。对于这种新手问题,我真的很抱歉 标准库已经有了
std::partition
,可以自己进行分区——将集合分为满足指定条件的项和不满足指定条件的项。所以,要进行分区,我们只需要提供一个合适的谓词

在这种情况下,我们需要一个简单的比较,比如:
returnx。但是,每次传递轴值都会变得很困难
std::partition
只是从集合中传递一个值,并询问:“这是否通过了测试?”您无法告诉
std::partition
当前的pivot值是什么,并让它在调用时将其传递给例程。当然,这是可以做到的(例如,Windows中的许多枚举函数都是这样工作的),但它会变得相当笨拙

当我们调用
std::partition
时,我们已经选择了pivot值。我们想要的是一种方法…将该值绑定到将传递给比较函数的参数之一。一种非常丑陋的方法是通过全局变量“传递”它:

int pivot;

bool pred(int x) { return x < pivot; }

void quick_sort(int *begin, int *end) { 
    if (end - begin < 2)
        return;

    pivot = choose_pivot(begin, end);

    int *pos = std::partition(begin, end, pred);
    quick_sort(begin, pos);
    quick_sort(pos, end);
}
这里我们又有了几乎相同的模式:创建一个存储一些相关状态的函数对象,然后重复应用该函数对象的
操作符()
,以完成实际工作


  • 我们可以分为小于或等于,而不是大于。或者我们可以创建三个组:小于、等于、大于。后者可以在存在许多重复项的情况下提高效率,但目前我们真的不在乎
  • 关于lambda表达式,我们需要了解的远不止这些——我简化了一些事情,完全忽略了我们目前不关心的其他事情

  • 我不确定我是否同意这里的投票结果。这是一个合法的编程问题。有一个阅读,这是一个C++不足;并不是所有的语言都会受到这种情况的影响。假设您想计算从特定位置调用函数的次数。您可以在函数中放置一个静态变量,但这将计算所有调用,并且无法重置。相反,您可以创建一个以计数作为成员变量的函数类,并为每个感兴趣的调用站点创建不同的函数对象。@molbdnilo您能解释一下吗?
    class pred { 
        int pivot;
    public:
        pred(int pivot) : pivot(pivot) {}
    
        bool operator()(int x) { return x < pivot; }
    };
    
    void quick_sort(int *begin, int *end) { 
        if (end-begin < 2)
            return;
    
        int pivot = choose_pivot(begin, end);
    
        int *pos = std::partition(begin, end, pred(pivot));        
        quick_sort(begin, pos);
        quick_sort(pos, end);
    }
    
    void quick_sort(int *begin, int *end) { 
        if (end-begin < 2)
            return;
    
        int pivot = find_pivot(begin, end);
    
        auto pos = std::partition(begin, end, [pivot](int x) { return x < pivot; });
        quick_sort(begin, pos);
        quick_sort(pos, end);
    }
    
    double largest = * std::max_element(begin, end);
    std::for_each(begin, end, [largest](double d) { return d/largest; });