Как мне создать набор с std :: pair, который отсортирован на основе :: second пары, используя bind - PullRequest
4 голосов
/ 02 июня 2010

Я знаю, что мог бы использовать следующее:

template <typename Pair> 
struct ComparePairThroughSecond : public std::unary_function<Pair, bool>
{ 
    bool operator ()(const Pair& p1, const Pair& p2) const
    {  
        return p1.second < p2.second; 
    } 
};

std::set<std::pair<int, long>, ComparePairThroughSecond> somevar;

но подумал, можно ли это сделать с boost :: bind

Ответы [ 2 ]

3 голосов
/ 04 июня 2010

Как насчет следующего. Я использую boost :: function, чтобы «стереть» фактический тип компаратора. Компаратор создан с использованием boost: bindself.

  typedef std::pair<int, int> IntPair;
  typedef boost::function<bool (const IntPair &, const IntPair &)> Comparator;
  Comparator c = boost::bind(&IntPair::second, _1) < boost::bind(&IntPair::second, _2);
  std::set<IntPair, Comparator> s(c);

  s.insert(IntPair(5,6));
  s.insert(IntPair(3,4));
  s.insert(IntPair(1,2));
  BOOST_FOREACH(IntPair const & p, s)
  {
    std::cout << p.second;
  }
0 голосов
/ 02 июня 2010

Проблема в том, что - если вы не пишете свой код в качестве шаблона или не используете функции C ++ 0x - вы должны назвать тип выражения boost :: bind. Но эти типы обычно имеют очень сложные имена.

Вывод аргумента шаблона в C ++ 98:

template<class Fun>
void main_main(Fun fun) {
   set<pair<int,long>,Fun> s (fun);
   …
}

int main() {
   main_main(…boost::bind(…)…);
}

С auto и decltype в C ++ 0x:

int main() {
   auto fun = …boost::bind(…)…;
   set<pair<int,long>,decltype(fun)> s (fun);
   main_main(boost::bind(…));
}

Что касается фактического выражения bind, я думаю, что-то вроде этого:

typedef std::pair<int,long> pil;
boost::bind(&pil::second,_1) < boost::bind(&pil::second,_2)

(непроверенные)

...