为什么标准库有find和find_if?

时间:2010-08-20 17:16:51

标签: c++ stl std design-rationale

find_if无法成为find的重载吗?那就是std::binary_search和朋友们这样做......

4 个答案:

答案 0 :(得分:15)

谓词是一个有效的东西,所以你可能会产生歧义。


考虑将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); 

†保存心灵阅读。

答案 1 :(得分:3)

这是Stroustrup所说的(The C ++ Programming Language,18.5.2):

  

如果find()find_if()有。{   同名,令人惊讶的遗憾   会产生的。一般来说,   _if后缀用于表示   algrithm采用谓词。

至于究竟是什么“含糊不清”,Steve Jessop在this SO question的答案(最高评分)中回答说。

(注意:这个问题实际上可能与此问题相同。我在C ++ arcania中做得不够聪明)。

答案 2 :(得分: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来执行此操作查找操作?为解决这个问题,他们创建了两个函数名称。

答案 3 :(得分:-2)

您当然可以使用某种等式谓词在find方面实现find_if

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

此外,C ++的语法是“你不为你不使用的东西买单”,而且你通常希望你不想为简单的比较做一个谓词评估。< / p>