【问题标题】:Advantage of C++ functor use for comparison使用 C++ 函子进行比较的优势
【发布时间】:2017-06-26 06:29:49
【问题描述】:

我在这里看过很多文章,但在比较的情况下,我仍然没有弄清楚仿函数类相对于简单函数的优势。所以我有一个代码摘录,他们想要通过简单地遍历每个字符并从左到右比较优先级的 ASCII 代码来对 unsigned char * 的向量进行排序。

函子是

class Sorter {
private:
    unsigned int length;
public:
    Sorter( unsigned int _length ): length( _length ) {}
    bool operator()( const unsigned char* keyl, const unsigned char* keyr ) { return cmpKey( keyl, keyr, length ); }
};

cmpKey() 函数基本上完成了我上面描述的操作。对数据进行排序的调用是

sort( localList.begin(), localList.end(), Sorter( 100 ) );

其中 100 是每个字符串的长度。所以,我读到仿函数具有存储从调用到调用的阶段的优点,并允许将类用作普通函数。我有两个问题:

  1. 在这种情况下这样做有什么好处?

  2. 将创建多少个Sorter 类的实例?是只有1个还是和locaList的元素一样多?

【问题讨论】:

  • 什么是cmpKey(),您为什么需要length
  • 如果没有函子,您如何将100 作为第三个参数传递给cmpKey

标签: c++ function stdvector functor


【解决方案1】:
  1. 优点是可以存储状态。在你的情况下,状态是length=100
  2. 调用Sorter(100) 时会创建一个函子。它可以被复制少量次(例如调用sort()),但不是针对每个元素。

【讨论】:

  • 据我了解,每次将length 参数传递给一个简单函数的成本要比使用仿函数大。我还假设,如果调用之间没有共同的状态,那么就没有其他优势可以使函子更受欢迎。这是正确的吗?
  • @mgus 将长度作为参数的函数不允许作为排序的第三个参数。这不是成本问题,而是正确类型的问题。
  • @mgus:更喜欢函子的另一个原因是您可以对它们使用部分模板特化,而普通函数则不允许。正如 Caleth 所说,您不能length 传递给普通函数。试试看。
【解决方案2】:

仿函数的主要用途是在运行时创建具有某种状态的函数。这在您需要一个函数来拥有一些信息但您不能将此信息作为参数传递给函数的场景中很重要。一个常见的例子是在像std::sort 这样的算法中,比较器函数必须只接受两个参数(要比较的东西),所以你不能只传递额外的信息作为参数。相反,您必须在运行时创建一个函数对象并在构造函数中传递该信息。

这基本上就是你打电话时所做的事情

 sort( localList.begin(), localList.end(), Sorter( 100 ) );

您正在创建一个 Sorter 函数,其中在构造函数时传递有关 100 的信息。调用它仍然只需要两个参数,因此这将在std::sort 算法中起作用。除了std::bind 之类的东西之外,没有办法用常规函数来做到这一点。

【讨论】:

  • std::bind 未被弃用,并构造了一个未指定(即实现定义)类型的函子
猜你喜欢
  • 1970-01-01
  • 2011-11-06
  • 2015-04-12
  • 2013-03-24
  • 1970-01-01
  • 2020-05-28
  • 2021-09-23
  • 2016-04-26
  • 1970-01-01
相关资源
最近更新 更多