ぷろみん

プログラミング的な内容を扱ってます

探して見つかった場合と見つからなかった場合の処理

C++14の機能を利用しているのでコンパイラによってはビルドが通らないです。

ありがち

処理の分割がいまいちで、コードを読む時に分かりにくいです。
また、for内で読み込みと書き込みを同時に行っているのは良くない書き方の兆候です。

#include<vector>
#include<utility>

int main(){
    std::vector<std::pair<bool, int>> v;
    // スコープが長いフラグ変数は怖い
    bool find = false;
    for(auto &&item: v){
        if(item.first){
            // ここでうっかり要素の追加とかすると危険な可能性がある
            item.second = 5;
            find = true;
            break;
        }
    }
    
    if(find){
        // ...
    } else {
        // ...
    }
}

標準ライブラリ

こういう処理はfind_ifを使うと良い感じに書けます。

#include<vector>
#include<utility>
#include<algorithm>

int main(){
    std::vector<std::pair<bool, int>> v;
    auto result = std::find_if(v.begin(), v.end(), [](const auto &item){
        return item.first;
    });
    
    // ちょっとここがダサい
    if(result != v.end()){
        result->second = 5;
        // ...
    } else {
        // ...
    }
}

linq的なアプローチ

何となく意図が掴めれば良いという感じで書いたコードなのでちゃんと動きません。

しっかりとしたlinq的な挙動が良いのならcpplinqを参照してください。
LINQ for C++ - Home

要するに対象を絞った後で処理をするテンプレートの様なものです。

このままだと上手く代入できません。
この辺の問題でしょうか?どちらにしろ理解不足です。
c++ - std::optional specialization for reference types - Stack Overflow

#include<vector>
#include<utility>
#include<experimental/optional>

template<class Container, class Func>
auto Where(Container &v, Func func)
// optionalにはautoが効かない。ぐぬぬ
-> std::experimental::optional<typename Container::value_type>
{
    for(auto &&item: v){
        if(func(item)){
            return item;
        }
    }
    return std::experimental::nullopt;
}

int main(){
    std::vector<std::pair<bool, int>> v;
    auto target = Where(v, [](auto&& item){ return item.first; });
    
    if(target){
        // ここでの代入が上手く機能しないのでもう少し考える必要がある
        (*target).second = 5;
        // ...
    } else {
        // ...
    }
}