我有一个本质上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);
}
Run Code Online (Sandbox Code Playgroud)
都好。然后,我想创建一个find()接受任意谓词而不是值的重载-我已经尝试过:
int my::find(const std::function<bool(const T&)>& pred) {
auto iter = std::find(this->data.begin(), this->data.end(), pred);
...
}
Run Code Online (Sandbox Code Playgroud)
并且:
template <typename P>
int my::find(P&& pred) {
auto iter = ...
}
Run Code Online (Sandbox Code Playgroud)
但是这两种情况都无法编译,因为“编译器”试图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; }
Run Code Online (Sandbox Code Playgroud)
该算法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);
...
}
Run Code Online (Sandbox Code Playgroud)
为了与标准库中的函数名称保持一致,我认为您还应该将函数名称更改为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);
...
}
Run Code Online (Sandbox Code Playgroud)