2012-01-27 12 views
14

Tengo un código que compila bien en VS 10.0 pero después de insertar algunos elementos en el siguiente mapa Pedidos, recibo un error de" operador no válido < "en la biblioteca de depuración de Microsoft. Mi operador menos es simple, solo compara la cadena de 8 bytes char por char. ¿Alguien tiene alguna idea de por qué recibiría este error?Operador STL less y error "operador no válido <

Gracias, Mike

typedef struct MY_orderID_t 
{ 
    char orderID[8]; 
} MY_orderID_t; 

struct std::less<MY_orderID_t> 
{ 
    bool operator()(const MY_orderID_t& k1, const MY_orderID_t& k2) const 
    { 
     for(int i=0; i < 8; i++) 
     { 
      if(k1.orderID[i] < k2.orderID[i]) 
      return(true); 
     } 
     return(false); 
    } 
}; 

std::map< MY_orderID_t, MY_order_t > Orders[5]; 

Respuesta

0

Además de cualquier otro tipo de error, que no veo por el momento, no se permite esta construcción:

struct std::less<MY_orderID_t> 
{ /**/ } 

std::less es ya un tipo, entonces no puedes redefinirlo como otro tipo.

+0

Y [este otro post] (http://stackoverflow.com/questions/2282349/specialization-of-templateclass-tp-struct-stdless-in- different-namespace) muestra la forma correcta de especializar 'std :: less'. –

27

yo creo que el problema aquí es que su método para comparar dos MY_orderID_t 's no es un strict weak order, el tipo de ordenar relación requerida por el STL C++. Para ser un orden débil estricta, el operador menor que debe tener las siguientes cuatro propiedades:

  1. Irreflexivity: < x x siempre es falsa.
  2. Antisimetría: Si x < y, entonces y < x siempre es falso.
  3. Transitivity: Si x < yy < z, entonces x < z es siempre cierto.
  4. Transitividad de equivalencia: Si x y y son incomparables y y y z son incomparables, entonces x y z son incomparables.

En este momento, su pedido no obedece a las propiedades (2) o (3).

* En primer lugar, (2) se viola por el siguiente texto:

(0, 4) < (2, 2) 
(2, 2) < (0, 4) 

* En segundo lugar, (3) se viola, porque

(0, 1) < (2, 0) < (-1, 1) 

// but 

(0, 1) < (-1, 1) // Fail 

Para solucionar este problema, en lugar de utilizar la comparación se Actualmente tienen, en lugar de utilizar un lexicographical comparison como éste:

return std::lexicographical_compare(k1.orderID.begin(), k1.orderID.end(), 
            k2.orderID.begin(), k2.orderID.end()); 

Esta comparación es una ordenación estrictamente débil y es lo que utilizan todos los contenedores STL por defecto. El cambio a esta comparación obedece a las propiedades (1) - (4) y debe hacer que todo funcione correctamente.

Espero que esto ayude!

+0

Para obtener más información, consulte este excelente artículo: [Order I Say!] (Http://cpp-next.com/archive/2010/02/order-i-say/). – ildjarn

3

@templatetypedef aborda los requisitos para una especialización std::less para ser utilizado con map, desde un punto de vista puramente sintáctico:

  • Es necesario #include<functional> y <map>

  • se echa en falta } entre char orderID[8]; y MY_orderID_t; en la línea siguiente.

  • y:

    struct std::less<MY_orderID_t> 
    { 
        /* ... */ 
    }; 
    

    debería ser:

    namespace std { 
    template <> 
    struct less<MY_orderID_t> 
    { 
        /* ... */ 
    }; 
    } 
    
5

@templatetypedef te dice lo que está mal con su versión actual.

Aquí es una solución mucho más legible:

struct MY_orderID_type 
{ 
    char orderID[8]; 
    bool operator<(const MY_orderID_type& other) const 
    { return memcmp(orderID, other.orderID, 8) < 0; } 
}; 

std::map< MY_orderID_type, MY_order_type > Orders;