C++ C++;函子优势-保持状态
我确实研究了函子的整个概念,不幸的是,我不能理解函子相对于典型函数的真正优势 根据一些学术脚本,函子可以持有不同于函数的状态。 有人能用一些简单易懂的例子来详细说明这一点吗C++ C++;函子优势-保持状态,c++,functor,C++,Functor,我确实研究了函子的整个概念,不幸的是,我不能理解函子相对于典型函数的真正优势 根据一些学术脚本,函子可以持有不同于函数的状态。 有人能用一些简单易懂的例子来详细说明这一点吗 我真的不明白为什么典型的、常规的函数不能做同样的事情。对于这种新手问题,我真的很抱歉
我真的不明白为什么典型的、常规的函数不能做同样的事情。对于这种新手问题,我真的很抱歉作为一个很小的演示,让我们考虑一个快速排序。我们选择一个值(通常称为“pivot”),并将输入集合分为比较小于pivot的集合和比较大于或等于pivot1的集合 标准库已经有了
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; });