我有一个基本上是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; }
答案 0 :(得分:6)
算法std::find
将始终将其第三个参数视为由operator==
与给定序列中的元素进行比较的值。您传入的谓词无法与该类的T
实例进行比较,因此会导致编译器错误。
您正在寻找std::find_if
(重载#3-4),它将谓词作为第三个参数。
答案 1 :(得分:5)
使用谓词时,请使用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);
...
}