2017-12-21 9 views
2

私は一般的に書いているコードの多くは "このコンテナをループし、いくつかの基準に一致する要素にXを実行する"というパターンに従っていることがわかります。多くの場合、このようになります要素を一致させるためにループをクリーンアップ

は:

std::vector<int> theList(10); 
std::iota(theList.begin(), theList.end(), 0); 

for (auto i : theList) 
{ 
    if ((i % 2) == 0) 
    { 
     //Do something with i 
    } 
} 

私はこれらの例でif文を好きではない - 彼らは醜いだと本当にループのロジックで何が起こっているのかを損ないます。

私が望むのは、この問題を解決するためのよりよい方法です。問題の中心はうまく表現されます。

私の最高の試みは、これまですべてが素敵ではありません。

std::vector<int> theList(10); 
std::iota(theList.begin(), theList.end(), 0); 

auto criteria = [](const int& i) -> bool { return (i % 2) == 0; }; 

for (auto it = std::find_if(theList.begin(), theList.end(), criteria); 
    it != theList.end(); 
    it = std::find_if(++it, theList.end(), criteria) 
    ) 
{ 
    std::cout << *it << ", "; 
} 

このパターンはきれいな方法でstd::algorithmにしてその方法を作る必要があるように感じます。

これを行うには良い方法がありますか?

+0

'がありますstd :: remove_if'を使ってリストをフィルタリングします。他の言語の 'filter'高次関数と同じです。しかし、フィルタリングされたリストは、別々のメモリを格納する必要があります。 – Gassa

答えて

1

あなたはこのために、簡単な高次機能を作成することができます。

template <typename Range, typename Predicate, typename F> 
void for_items_matching(Range&& r, Predicate&& p, F&& f) 
{ 
    for(auto&& x : r) 
    { 
     if(p(x)) { f(x); } 
    } 
} 

使用例:いくつかのリファクタリングとヘルパークラス/機能付き

auto criteria = [](const int& i) -> bool { return (i % 2) == 0; }; 
for_items_matching(theList, criteria, [](auto&& item) 
{ 
    std::cout << item << ", "; 
}) 

をあなたが何かに終わる可能性like:

for_items_of(theList) 
    .matching(criteria) 
    .execute([](auto&& item){ std::cout << item << ", "; }); 

もう1つの可能性は、今後のRanges TSです。

+0

ありがとうございます。これは現時点でできる最善のものと思われます。下の@ vlad-from-moscowに非常によく似た答えです(私は両方を使用すると思いますが)。 – fwgx

1

あなたが正しく理解していれば、標準アルゴリズムstd::for_each_ifが必要です。例えば

#include <iostream> 
#include <iterator> 
#include <numeric> 

template<class InputIterator, class Predicate, class Function> 
Function for_each_if(InputIterator first, 
        InputIterator last, 
        Predicate predicate, 
        Function f) 
{ 
    for (; first != last; ++first) 
    { 
     if (predicate(*first)) f(*first); 
    } 

    return f; 
} 

int main() 
{ 
    int a[10]; 

    std::iota(std::begin(a), std::end(a), 0); 

    for_each_if(std::begin(a), std::end(a), 
     [](int x) { return x % 2 == 0; }, 
     [](int x) { std::cout << x << ", "; }); 

    std::cout << std::endl; 

    return 0; 
} 

プログラムの出力がある

0, 2, 4, 6, 8, 

しかし、実際に私が標準に含めるための提案をしたものの、C++には、このような標準アルゴリズムはありません。:)

関連する問題