簡體   English   中英

如何使用一些boost庫使std :: find_if和std :: map一起工作?

[英]How can I make std::find_if and std::map work together using some boost library?

這個問題的靈感來自另一個提出這個問題的話題

從地圖容器中查找大於用戶指定值的第一個值

這可以通過幾種方式解決。 典型的C ++ 03解決方案定義了一個專用函數(或函子),並將其作為第三個參數傳遞給std::find_if

在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);

這里arg1boost::phoenix::arg_names命名空間中定義的boost::phoenix::arg_names函數對象,表達式arg1>4計算到另一個std::find_if函數,然后傳遞給std::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 &為參數的const std::pair &函數。 我的直覺告訴我,提升有這個解決方案。 :-)

實際上,Boost.Fusion和Boost.Phoenix正是你想要的內置。

如果一個包含必要的頭來使std::pair<>作為一個符合的Fusion序列 ,那么可以使用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"
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM