12

不能find_if只是超载find吗?朋友也是这样的std::binary_search。。。

4

4 回答 4

19

谓词是可以找到的有效事物,因此您可能会产生歧义。


考虑find_if改名find,那么你有:

template <typename InputIterator, typename T>
InputIterator find(InputIterator first, InputIterator last, const T& value);

template <typename InputIterator, typename Predicate>
InputIterator find(InputIterator first, InputIterator last, Predicate pred);

那么,应该怎么做:

find(c.begin(), c.end(), x); // am I finding x, or using x to find?

与其尝试提​​出一些复杂的解决方案来区分x(这并不总是可以做到*),不如将它们分开更容易。

*这将是模棱两可的,无论您的方案是什么或它可能多么强大†:

struct foo
{
    template <typename T>
    bool operator()(const T&);
};

bool operator==(const foo&, const foo&);

std::vector<foo> v = /* ... */;
foo f = /* ... */; 

// f can be used both as a value and as a predicate
find(v.begin(), v.end(), f); 

†节省读心术。

于 2010-08-20T17:25:38.117 回答
4

这是 Stroustrup 所说的(C++ 编程语言,18.5.2):

如果find()find_if()有相同的名字,就会产生令人惊讶的模棱两可。通常, _if后缀用于表示算法采用谓词。

至于“模棱两可”到底是什么,史蒂夫·杰索普在他对这个 SO question的(评价最高的)回答中回答了这个问题。

(注意:这个问题实际上可能与这个问题相同。我在 C++ arcania 中不够聪明,无法决定)。

于 2010-08-20T17:32:34.857 回答
1

它不能具有相同的名称,因为会有歧义。假设我们有一个find重载而不是find_if. 然后假设:

// Pseudo-code
struct finder
{
    bool operator()(const T&) const { ... }
    bool operator==(const finder& right) const { ... }
}

std::vector<finder> finders;

finder my_finder;

std::find(finders.begin(), finders.end(), my_finder);

find无法解决不一致:它应该尝试finder在容器中查找 ,还是使用finder进行查找操作?为了解决这个问题,他们创建了两个函数名。

于 2010-08-20T17:32:15.327 回答
-2

您当然可以使用某种相等谓词来实现findfind_if

我猜真正的原因是您可以find相当容易地实现并为典型遇到的类型提供高性能的专门实现;如果您使用find_if,则传入的谓词可以任意复杂,这使库实现者的优化范围更小。

此外,C++ 的理念是“不用为不使用的东西付费”,如果可以进行简单的比较,您通常会期望您不想为谓词评估付费。

于 2010-08-20T17:32:17.677 回答