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++ には「使用しないものにはお金を払わない」という哲学があり、通常、単純な比較で済むのであれば、述語の評価にお金を払いたくないはずです。