find_if
无法成为find
的重载吗?那就是std::binary_search
和朋友们这样做......
答案 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>