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の発言です(The C++ Programming Language、18.5.2):
もし
find()とfind_if()が同じ名前だったら、驚くべきあいまいさが生じたでしょう。一般に、_ifサフィックスは、アルゴリズムが述語を取ることを示すために使用されます。
その「あいまいさ」が正確に何であるかについて、Steve Jessop は、この SO の質問に対する彼の (最高評価の) 回答で答えました。
(注:その質問は、実際にはこれと同じ質問とみなされる可能性があります。私はC ++のアルカニアで判断できるほど頭が良くありません)。
あいまいさがあるため、同じ名前を持つことはできません。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て検索操作を実行する必要がありますか? この問題を解決するために、彼らは 2 つの関数名を作成しました。
ある種の等価述語を使用するfindという点で、確かに実装できます。find_if
find本当の理由は、かなり簡単に実装でき、典型的な遭遇する型に対してパフォーマンスの高い特殊な実装を提供できるためだと思います。を使用している場合find_if、渡す述語は任意に複雑にすることができ、ライブラリの実装者に最適化の範囲を狭めます。
また、C++ には「使用しないものにはお金を払わない」という哲学があり、通常、単純な比較で済むのであれば、述語の評価にお金を払いたくないはずです。