为什么标准库有find和find_if?

发布于 2024-09-15 19:46:21 字数 106 浏览 2 评论 0原文

find_if 不能只是 find 的重载吗?这就是 std::binary_search 和朋友们这样做的......

Couldn't find_if just be an overload of find? That's how std::binary_search and friends do it...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梨涡少年 2024-09-22 19:46:21

谓词是一个有效的东西,所以你可能会得到歧义的结果。


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

†保存读心术。

A 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.

孤凫 2024-09-22 19:46:21

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

如果 find()find_if()
相同的名字,令人惊讶的歧义
就会产生这样的结果。一般来说,
_if 后缀用于表示
算法需要一个谓词。

至于“歧义”到底是什么,史蒂夫·杰索普在他对 这个问题

(注意:这个问题实际上可能与这个问题是同一个问题。我在 C++ arcania 方面不够聪明,无法做出决定)。

Here's what Stroustrup said (The C++ Programming Language, 18.5.2):

If find() and find_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).

花开雨落又逢春i 2024-09-22 19:46:21

它不能具有相同的名称,因为这样会产生歧义。假设我们有一个 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,还是使用 < code>finder 进行查找操作?为了解决这个问题,他们创建了两个函数名称。

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.

得不到的就毁灭 2024-09-22 19:46:21

您当然可以使用某种等式谓词根据 find_if 来实现 find

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

此外,C++ 的理念是“你不必为不使用的东西付费”,并且你通常会认为,如果简单的比较就可以的话,你就不想为谓词评估付费。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文