2011-01-25 22 views

Respuesta

6

el iterador map te dará un pair donde first es la clave int y second es el valor del mapa pair, así que si h y un iterador it, querrá el mínimo de todos los valores it->second.first. La función min_element espera una función de comparación para su tercer argumento, por lo que debe crear una función de comparación que proyecte second.first de sus dos argumentos.

Vamos a empezar con algunos typedefs para hacer el código más legible:

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

vamos a utilizar Boost.Lambda por sus operadores sobrecargados, que nos permite utilizar operator<. Boost.Bind puede vincular variables miembro así como funciones de miembros, por lo que también lo aprovecharemos.

#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; 

Eso también funcionará con boost::lambda::bind.

2

bind no puede hacer esto por sí mismo, porque first y second están expuestos como campos, no métodos (por lo que no puede salir con algo así como mem_fun).

Usted puede hacer esto utilizando su propio funtor, por supuesto, sin embargo:

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

También conocido como 'select1st' en algunas bibliotecas C++. – ephemient

+0

@ephemient: cierto: no era consciente de que ya estaba incluido con el STL de SGI. En ese caso, recomendaría dejar el nombre de esta manera porque SGI admite cualquier interfaz parecida a una pareja, mientras que esta solo funciona con 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; 

(Por supuesto, alguien va a quejarse de que esto es un abuso de STL y que éstas son extensiones no están en el C++ estándar ...)

+0

Bueno, me quejaría de las extensiones no estándar, pero en lo que respecta al "abuso de STL" creo que está perfectamente bien :) +1. Afortunadamente, los bits no estándar son fáciles de escribir. –

Cuestiones relacionadas