2009-05-15 12 views
13

Quiero encontrar el primer elemento en un vector ordenado que tiene un campo menor que algún valor x.
Necesito proporcionar una función de comparación que compare 'x' con el valor interno en MyClass, pero no puedo calcular la declaración de la función.
¿No puedo simplemente sobrecargar '<', pero ¿cómo hago esto cuando los argumentos son '& MyClass' y 'float'?función de comparación para upper_bound/lower_bound

float x; 
std::vector<MyClass>::iterator last = std::upper_bound(myClass.begin(),myClass.end(),x); 

Respuesta

15

¿Qué función pasó al algoritmo de ordenación? Debería poder usar el mismo para upper_bound y low_bound.

La manera más fácil de hacer que la comparación funcione es crear un objeto ficticio con el campo clave establecido en el valor de búsqueda. Entonces la comparación siempre será entre objetos similares.

Edit: Si por alguna razón no puede obtener un objeto ficticio con el valor de comparación adecuado, entonces puede crear un funtor de comparación. El funtor puede proporcionar tres sobrecargas para el operador():

struct MyClassLessThan 
{ 
    bool operator() (const MyClass & left, const MyClass & right) 
    { 
     return left.key < right.key; 
    } 
    bool operator() (const MyClass & left, float right) 
    { 
     return left.key < right; 
    } 
    bool operator() (float left, const MyClass & right) 
    { 
     return left < right.key; 
    } 
}; 

Como se puede ver, ese es el largo camino por recorrer al respecto.

+0

Ese fue el problema, la función de ordenamiento requiere dos referencias a objetos MyClass. La función de búsqueda debe tomar un MyClass y un float. El mismo problema para usar bind2nd() el operador –

+0

() para comparar cosas, ¿¡ahora por qué no pensé en eso! Cuanto más uso STL, más me encanta Python. gracias –

+0

¿no debería ser const MyClass & left, const MyClass & right? – chmike

0

Creo que lo que necesita es std::bind2nd(std::less<MyClass>(), x). Pero, por supuesto, el operador < debe definirse para MyClass.

Edit: oh y creo que necesitarás un constructor para MyClass que acepte solo un flotador para poder convertirlo implícitamente. Sin embargo, podría haber una mejor manera de hacer esto.

6

Puede mejorar aún más la solución de Mark creando una instancia estática de MyClassLessThan en MiClase

class CMyClass 
{ 
    static struct _CompareFloatField 
    { 
     bool operator() (const MyClass & left, float right) //... 
     // ... 
    } CompareFloatField; 
}; 

De esta manera se puede llamar de límite distinto de la siguiente manera:

std::lower_bound(coll.begin(), coll.end(), target, CMyClass::CompareFloatField); 

Esto hace que sea un poco más legible

+1

Todavía necesitaría un objeto ficticio y un operador() para cada miembro, pero el suyo es más claro al leer el intento. Gracias –

Cuestiones relacionadas