How can I find the value on the map using binders only

When searching in the second value of the map, I use somthing, as shown below:

typedef std::map<int, int> CMyList;
static CMyList myList;

template<class t> struct second_equal
{
    typename typedef t::mapped_type mapped_type;
    typename typedef t::value_type value_type;

    second_equal(mapped_type f) : v(f)   {};
    bool operator()(const value_type &a) { return a.second == v;};

    mapped_type v;
};
...    
int i = 7;
CMyList::iterator it = std::find_if(myList.begin(), myList.end(), 
                                    second_equal<CMyList>(i));

Question: How can I make such a find in one line without providing an independent written template?

+3
source share
4 answers

Use the selector to select the first or second element from the value_type that you get from the map. Use a binder to bind the value (i) to one of the function arguments std::equal_to. Use composer to use selector output as another argument to the equal_to function.

//stl version
CMyList::iterator it = std::find_if(
    myList.begin(), 
    myList.end(), 
    std::compose1(
        std::bind2nd(equal_to<CMyList::mapped_type>(), i), 
        std::select2nd<CMyList::value_type>())) ;

//Boost.Lambda or Boost.Bind version
CMyList::iterator it = std::find_if(
    myList.begin(), 
    myList.end(), 
    bind( &CMyList::mapped_type::second, _1)==i);
+8
source

. , ( ++ 0x) - _.second .

:

template <class Second>
class CompareSecond
{
public:
  CompareSecond(Second const& t) : m_ref(t) {} // actual impl use Boost.callparams
  template <class First>
  bool operator()(std::pair<First,Second> const& p) const { return p.second == m_ref; }
private:
  Second const& m_ref;
};

:

template <class Second>
CompareSecond<Second> compare_second(Second const& t)
{
  return CompareSecond<Second>(t);
}

.

CMyList::iterator it = std::find_if(myList.begin(), myList.end(), compare_second(i));

, .

, , , , , .

:
, STL, , :

 CMyList::iterator it = toolbox::find_if(myList, compare_second(i));

(imho) , auto .

0

Boost Lambda

CMyList::iterator it = std::find_if(
      myList.begin(), myList.end(), 
      boost::lambda::bind(&CMyList::value_type::second, boost::lambda::_1) == i);
0

. , .

template <typename Iter, typename T>
Iter find_second(Iter first, Iter last, T value) {
    while (first != last) {
        if (first->second == value) {
            return first;
        }
        ++first;
    }
    return first;
}

, .

, - . , , , . , , - Matthieu M..

-1

Source: https://habr.com/ru/post/1722778/


All Articles