2011-01-25 2 views

Répondre

6

le map iterator vous donnera un pairfirst est la clé int et second est pair valeur de la carte, donc si vous h ad un itérateur it, vous voudriez le minimum de toutes les valeurs it->second.first. La fonction min_element attend une fonction de comparaison pour son troisième argument, vous devez donc créer une fonction de comparaison qui projette second.first de ses deux arguments.

Nous allons commencer par quelques typedefs pour rendre plus lisible le code:

typedef std::pair<short, float> val_type; 
typedef std::map<int, val_type> map_type; 
map_type m; 

Nous allons utiliser Boost.Lambda pour ses opérateurs surchargés, ce qui nous permet d'utiliser operator<. Boost.Bind peut lier les variables membres aussi bien que les fonctions membres, donc nous en profiterons aussi.

#include <boost/bind.hpp> 
#include <boost/lambda/lambda.hpp> 
using boost::bind; 

// Comparison is (_1.second.first < _2.second.first) 
std::cout << 
    std::min_element(m.begin(), m.end(), 
    bind(&val_type::first, bind(&map_type::iterator::value_type::second, _1)) 
    < 
    bind(&val_type::first, bind(&map_type::iterator::value_type::second, _2)) 
)->second.first; 

Cela fonctionnera également avec boost::lambda::bind.

2

bind ne peut le faire par lui-même, parce que first et second sont exposés sous forme de champs, et non pas des méthodes (vous ne pouvez donc pas vous en sortir avec quelque chose comme mem_fun).

Vous pouvez le faire en utilisant votre propre foncteur bien sûr que:

template <typename F, typename S> 
struct select_first : std::binary_function<std::pair<F, S>&, F&> 
{ 
    F& operator()(std::pair<F, S>& toConvert) 
    { 
     return toConvert.first; 
    } 
}; 
+1

Également appelé 'select1st' dans certaines bibliothèques C++. – ephemient

+0

@ephemient: True - n'était pas au courant qu'il était déjà inclus dans le STL de SGI. Dans ce cas, je recommanderais de laisser le nom de cette façon parce que SGI supporte n'importe quelle interface de type paire, alors que celle-ci ne fonctionne qu'avec std :: pair. –

5
min_element(map.begin(), map.end(), 
      compose2(less<short>(), 
        compose1(select1st<pair<short, float> >(), 
           select2nd<map<int, pair<short, float> 
              >::value_type>()), 
        compose1(select1st<pair<short, float> >(), 
           select2nd<map<int, pair<short, float> 
              >::value_type>())) 
      ).second.first; 

(Bien sûr, quelqu'un va se plaindre que c'est un abus de STL et que ceux-ci sont des extensions pas dans le C++ norme ...)

+0

Eh bien, je me plaindrais d'extensions non standard, mais en ce qui concerne "l'abus de STL", je pense que c'est parfaitement bien :) +1. Heureusement, les morceaux non standard sont faciles à écrire. –

Questions connexes