使用 std::find 和用户提供的谓词 - 自制的 find() 重载

Using std::find with user supplied predicate - homemade find() overload

本文关键字:find 重载 std 用户 使用 谓词      更新时间:2023-10-16

我有一个类,它本质上是一个具有一些附加功能的std::vector<T>。该类具有find(const T& value )方法,该方法将返回 value 或 -1 第一次出现的索引:

int my::find(const T& value) {
    auto iter = std::find(this->data.begin(), this->data.end(), value);
    if (iter == this->data.end())
        return -1;
    return std::distance(this->data.begin(), iter);
}

都很好。然后我想创建一个find()重载,它接受任意谓词而不是值 - 我已经尝试过:

int my::find(const std::function<bool(const T&)>& pred) {
    auto iter = std::find(this->data.begin(), this->data.end(), pred);
    ...
}

以及:

template <typename P>
int my::find(P&& pred) {
    auto iter = ...
}

但是这两种情况都无法编译,因为"编译器"试图在pred类型值的向量中查找pred,而不是将pred应用于值,即当我实例化my<int>时,我得到编译器错误,例如:

/usr/include/c++/5/bits/predefined_ops.h:194:17: error: no match for ‘operator==’ (operand types are ‘int’ and ‘const std::function<bool(const int&)>’)
  { return *__it == _M_value; }
算法

std::find将始终将其第三个参数视为一个值,该值与给定序列中的元素进行比较 operator== .您传入的谓词无法与类的T实例进行比较,因此会出现编译器错误。

您正在寻找std::find_if(重载 #3-4(,它将谓词作为第三个参数。

使用谓词时,请使用 std::find_if

int my::find(const std::function<bool(const T&)>& pred) {
    auto iter = std::find_if(this->data.begin(), this->data.end(), pred);
    ...
}

为了与标准库中的函数名称保持一致,我认为在使用谓词时,您也应该将函数名称更改为find_if

int my::find_if(const std::function<bool(const T&)>& pred) {
    auto iter = std::find_if(this->data.begin(), this->data.end(), pred);
    ...
}