【问题标题】:Using std::find with user supplied predicate - homemade find() overload将 std::find 与用户提供的谓词一起使用 - 自制 find() 重载
【发布时间】:2019-04-02 14:05:23
【问题描述】:

我有一个类,它本质上是一个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&lt;int&gt; 时得到如下编译器错误:

/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; }

【问题讨论】:

    标签: c++


    【解决方案1】:

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

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

    【讨论】:

    • 唷,我认为 cppreference 在遇到不同名称的重载时会重新启动它们的序数(查找重载 1、查找重载 2、find_if 重载 1、find_if 重载 2 ...)
    【解决方案2】:

    当你使用谓词时,使用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);
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-19
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多