2017-08-11 12 views
2

述語はイテレータの入力範囲から引数をとり、意図したとおりに操作することを理解しましたが、バイナリ述語とイテレータのペアを指定すると、コンテナの要素はどのように述語に渡されますか?述語を使用してサイズに応じてソートする

など。 std::sortは、デフォルトではアルファベット順に文字列のベクトルをソートし、それらを並べ替えるために、我々は次のように述語を渡すことができる大きさに応じて:だから

sort(vec.begin(), vec.end(), [](const string &a, const string &b) { 
    return a.size() < b.size(); 
}); 

、これはアルファベット順に大きさで文字列vecのベクトルをソートしていないことになっているが、私はこれがどのように起こっているのか理解できません。つまり、述語がどのようにベクトルの要素を引数として取っていて、どのようにソートしていますか?

+0

述語はそれだけで2つの要素を比較しています、何もソートされていません。 'std :: sort'は必要に応じて述語を呼び出し、要素のさまざまなペアを比較し、それらの順序を決定します。 –

答えて

2

std sortが呼び出されると、この関数の「通常の」バージョンはoperator<を使用して比較を実行します。あなたが理解したように、2つの文字列の比較は辞書的なものです(辞書のように)。 しかし、のような例を考えるstd::sort機能を開発した人:何operator<

  • ユーザーはありません

    1. は、述語が便利です

    それをソートするための別の方法は、ここでそれがある場合があります。述語(Igor Tandetnikのように)は、std::sort関数内で呼び出されます。

    ので、通常のバージョンで、std::sortはそのようなことでしょう:述語のバージョンで

    if(*a < *b) { 
    ... 
    } 
    

    を、それはほとんど同じことをするでしょう。その道を行く

    if(predicate(*a, *b)) { 
    ... 
    } 
    

    、あなたの述語operator<関数を置き換えます。

  • 0

    バイナリ述語は、コンテナの逆参照されたイテレータの型の2つのパラメータを必要とする呼び出し可能なオブジェクト(関数またはラムダを含む)以外のものではありません。その「役割」はソートアルゴリズムの比較基準を提供することです。

    std::sortアルゴリズムは、この関数または関数オブジェクトがBOOLに変換可能であり、最初の引数がソート順の第2引数の前にある場合にのみ(いわゆる場合、真得た値を返すことを期待弱い厳密注文)。 std::sortアルゴリズムは、要素を個別に比較するときに述語を要素に適用することによって、オブジェクトの与えられた範囲(コンテナの終わりを始める)を操作(ソート)します。

    あなたのケースでは、コンテナが文字列のベクトルの場合、逆参照されたイテレータはstd:stringとなり、ラムダは正常に動作します。

    コンクリートタイプに依存しないラムダでどのように動作するかを示すコード例ですが、コンテナ内のオブジェクトに少なくともsize()オペレーションを定義する必要があります。また、(この場合、私は述語を反転させてソート順を元に戻す)バイナリ述語は関数オブジェクトとして提供することができるか、を示しています。

    #include <algorithm> 
    #include <iostream> 
    #include <string> 
    #include <vector> 
    
    using Words = std::vector<std::string>; 
    
    struct CompareReverse 
    { 
        bool operator() (auto lhs, auto rhs) 
        { 
         return rhs.size() < lhs.size(); // less-than reversed! 
        } 
    }; 
    
    int main() 
    { 
        Words words { "red", "green", "blue", "wizard", "a", "letter", "very-long-word" }; 
    
        std::sort(words.begin(), words.end(), [](auto a, auto b) { return a.size() < b.size(); }); 
    
        for (auto w : words) 
         std::cout << w << std::endl; 
    
        std::sort(words.begin(), words.end(), CompareReverse()); 
    
        for (auto w : words) 
         std::cout << w << std::endl; 
    
        return 0; 
    } 
    
    関連する問題