6

この質問は、この質問を提起する別のトピックから着想を得ています。

マップコンテナからユーザー指定値より大きい最初の値を検索します

これはいくつかの方法で解決できます。典型的なC++03ソリュ​​ーションは、専用の関数(またはファンクター)を定義し、それをstd::find_if3番目の引数として渡します。

C ++ 11では、専用関数(またはファンクター)の定義を回避でき、代わりに次のように使用できますlambda

auto it = std:: find_if(m.begin(), mp.end(), 
                    [n](const std::pair<std::string, int> & x) -> bool
                       { return x.second > n; }
                   );

これは受け入れられた答えです。

私はまだ短くてクールな解決策を探しています。それがベクトルの場合、私はそれを利用するクールなソリューションを学び、Boost.Phoenixソリューションは非常に簡潔になります(ideone demo):

std::vector<int> v = ...;
auto it = std::find_if(v.begin(), v.end(), arg1 > 4);

これは名前空間でarg1定義されたファンクターオブジェクトであり、式は別のファンクターに評価され、それがに渡されます。boost::phoenix::arg_namesarg1>4std::find_if

簡単なテストは(ideone)、

std::cout<< (arg1 > 9)(v) << std::endl; //prints 0 if as v > 9 is false, else 1

//or store the functor first and then use it
const auto & f = arg1 > 9;
std::cout<<  f(v) << std::endl; //prints 0 if as v > 9 is false, else 1

私の質問は、同様の方法で地図の問題を解決したいということです。そのような解決策はありますか?何かのようなもの:

auto it = std::find_if(m.begin(),mp.end(), (???).second > n); //m is std::map

または、

auto it = std::find_if(m.begin(),mp.end(), at<1>(arg1) > n);  //m is std::map

それが機能するためには、式は引数at<1>(arg1) > 2を取るファンクターに評価される必要があります。const std::pair &私の腸の感覚は、ブーストがこの解決策を持っていることを教えてくれます。:-)

4

1 に答える 1

9

確かに、Boost.FusionとBoost.Phoenixには、まさにあなたが望むものが組み込まれています。

準拠するFusionシーケンスとして適応するためstd::pair<>に必要なヘッダーが含まれている場合は、Phoenixのレイジーバージョンを使用してまたはboost::fusion::at_c<>にアクセスできます(必ず)。std::pair<>::firststd::pair<>::second#include <boost/phoenix/fusion.hpp>

namespace phx = boost::phoenix;
using phx::arg_names::arg1;

auto it = std::find_if(m.begin(), m.end(), phx::at_c<1>(arg1) > n);

編集:完全なサンプル、VC ++ 2010 SP1 + Boost 1.47.0でテスト済み:

#include <algorithm>
#include <map>
#include <string>
#include <iostream>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/phoenix/fusion.hpp>

int main()
{
    namespace phx = boost::phoenix;
    using phx::arg_names::arg1;

    std::map<std::string, int> m;
    m["foo"]    = 1;
    m["bar"]    = 2;
    m["baz"]    = 3;
    m["qux"]    = 4;
    m["quux"]   = 5;
    m["corge"]  = 6;
    m["grault"] = 7;
    m["garply"] = 8;
    m["waldo"]  = 9;
    m["fred"]   = 10;
    m["plugh"]  = 11;
    m["xyzzy"]  = 12;
    m["thud"]   = 13;

    int const n = 6;
    auto it = std::find_if(m.cbegin(), m.cend(), phx::at_c<1>(arg1) > n);
    if (it != m.cend())
        std::cout << it->first << '\n'; // prints "fred"
}
于 2011-09-07T16:55:35.480 に答える