[C++] while or for find_if関数オブジェクトlambda

2294 ワード

どっちを選ぶ?
while
template
In find(In first, In last, const T& val)
{
    while(first!=last && *first!=val) ++first;
    return first;
}

for
template
In find(In first, In last, const T& val)
{
    for(In p = first; p != last; ++p)
        if(*p == val) return p;
    return last;
}
  • whileを優先しています.for以上のpのため、一部のコンパイラはこのpをどのように破棄するか分かりません.

  • find_if
    template
    In find_if(In first, In last, Pred pred)
    {
        while(first!=last && !pred(*first)) ++first;
        return first;
    }
    
    bool odd(int x) { return x%2;}
    
    void f(vector& v)
    {
        auto p = find_if(v.begin(), v.end(), odd);
        if(p!=v.end()) {
            // ...
        }
    }
    
  • パラメータ伝達を行う場合、()auto p = find_if(v.begin(), v.end(), odd);を加えないでください.
  • odd()と書くと、かっこをつけるとこの関数が呼び出されます.

  • 関数オブジェクト
    template
    In find_if(In first, In last, Pred pred)
    {
        while(first!=last && !pred(*first)) ++first;
        return first;
    }
    
    
    void f(list& v, int x)
    {
        auto p = find_if(v.begin(), v.end(), Larger_than(31));
        if(p!=v.end()) {}
        
        auto q = find_if(v.begin(), v.end(), Larger_than(x));
        if(q!=v.end()) {}
    }
    
    class Larger_than{
        int v;
    public:
        Larger_than(int vv): v{vv} {}
        bool operator()(int x) const { return x > v; }
    };
    
    // lambda
    void f(list& v, int x)
    {
        auto p = find_if(v.begin(), v.end(), [](double a) { return a > 31;});
        if(p!=v.end()) {}
        
        auto q = find_if(v.begin(), v.end(), [&](double a) { return a > x;});
        if(q!=v.end()) {}
    }
    
  • Larger_than(31)はクラスオブジェクトを初期化し、v31である.
  • pred(*first)、ここではLarger_than(*first)と解釈されるのは、bool operator()(int x) const { }を定義しているためであり、ここでx*firstである.

  • Programming -- Principles and Practice Using C++ (Second Edition) http://www.stroustrup.com/Programming/