Couldn't find_if
just be an overload of find
? That's how std::binary_search
and friends do it...
views:
156answers:
4A predicate is a valid thing to find, so you could arrive at ambiguities.
Consider find_if
is renamed find
, then you have:
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);
What shall be done, then, with:
find(c.begin(), c.end(), x); // am I finding x, or using x to find?
Rather than try to come up with some convoluted solution to differentiate based on x
(which can't always be done*), it's easier just to separate them.
*This would be ambiguous, no matter what your scheme is or how powerful it might be†:
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);
†Save mind reading.
It can't have the same name because there would be an ambiguity. Suppose that we had a find
overload instead of find_if
. Then suppose:
// 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);
The find
would have no way to resolve the inconsistency: Should it attempt to find the finder
in the container, or use the finder
to do the find operation? To solve this problem they created two function names.
You can certainly implement find
in terms of find_if
using some sort of equality predicate.
I would guess that the real reason is that you can implement find
fairly easily and provide performant specialised implementations for typical encountered types; if you are using find_if
, the predicate you pass in can be arbitrarily complex, which gives the library implementer less scope of optimisation.
Also, C++ has the philosphy of "you don't pay for what you don't use" and you'd normally expect that you don't want to pay for a predicate evaluation if a simple comparison will do.
Here's what Stroustrup said (The C++ Programming Language, 18.5.2):
If
find()
andfind_if()
had the same name, surprising abmiguities would have resulted. In general, the_if
suffix is used to indicate that an algrithm takes a predicate.
As to what exactly that "ambiguity" is, Steve Jessop answered that in his (top rated) answer to this SO question.
(note: that question may actually qualify as the same question as this one. I'm not quite smart enough in C++ arcania to decide).