不能find_if
只是超载find
吗?朋友也是这样的std::binary_search
。。。
4 回答
谓词是可以找到的有效事物,因此您可能会产生歧义。
考虑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);
†节省读心术。
这是 Stroustrup 所说的(C++ 编程语言,18.5.2):
如果
find()
和find_if()
有相同的名字,就会产生令人惊讶的模棱两可。通常,_if
后缀用于表示算法采用谓词。
至于“模棱两可”到底是什么,史蒂夫·杰索普在他对这个 SO question的(评价最高的)回答中回答了这个问题。
(注意:这个问题实际上可能与这个问题相同。我在 C++ arcania 中不够聪明,无法决定)。
它不能具有相同的名称,因为会有歧义。假设我们有一个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
进行查找操作?为了解决这个问题,他们创建了两个函数名。
您当然可以使用某种相等谓词来实现find
。find_if
我猜真正的原因是您可以find
相当容易地实现并为典型遇到的类型提供高性能的专门实现;如果您使用find_if
,则传入的谓词可以任意复杂,这使库实现者的优化范围更小。
此外,C++ 的理念是“不用为不使用的东西付费”,如果可以进行简单的比较,您通常会期望您不想为谓词评估付费。