Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problemas Con Std::set

Iniciado por DraKKaR, 27 de Diciembre de 2004, 11:25:02 PM

« anterior - próximo »

DraKKaR

 Hola, estoy teniendo problemillas usando la template std::set de la STLPort.

La cosa es ke kiero almacenar en un conjunto (std:set) una lista de triangulos que se van a representar. La cosa es que no quiero que se pinte 2 veces el mismo triangulo, por eso uso std::set, que se supone que es un contenedor donde todos sus elementos son únicos.

Lo stoy haciendo así:

class tri_indices_t
{
public:
 int a,b,c;

 tri_indices_t(void){ }
 tri_indices_t(const tri_indices_t &t){ operator=(t); }

 bool operator<(const tri_indices_t &t) const {
  return (a<t.a && b<t.b && c<t.c);
 }
 bool operator==(const tri_indices_t &t) const {
  return (a==t.a && b==t.b && c==t.c);
 }
 bool operator!=(const tri_indices_t &t) const {
  return (!operator==(t));
 }
 const tri_indices_t &  operator=(const tri_indices_t &t){
  a=t.a; b=t.b; c=t.c; return t;
 }
};


std::set<tri_indices_t> setTris;




Y para añadir cada triangulo al conjunto así:


for (unsigned int ifa=0; ifa<numfaces; ifa++)
{
               // añadir los 3 indices de cada cara
 unsigned int i3 = ifa*3;

 tri_indices_t auxt;
 auxt.a=pindices[i3+0];
 auxt.b=pindices[i3+1];
 auxt.c=pindices[i3+2];

 tris_added[itex].insert(auxt);

       }


El poblema es que, añadiendo 2 triangulos con vertices (0,1,2) y (0,2,3) no funciona, solo añade el primero, y no el segundo, como si el insert del set creyera que son el mismo triangulo.

¿Es un bug d set o que ocurre? PArece que si el tipo del set no es un tipo básico hace cosas raras con esto. Ya me ocurrió algo parecido con el std::map utilizando tipos no básicos como clave.

Juan Mellado

 El contenedor set utiliza por defecto el operador < para las comparaciones. Y el operador < que has definido no es "estricto" (no se me ocurre otra palabra para decirlo), y por tanto no establece un orden bien definido.

En tu ejemplo:
(0,1,2) < (0, 2, 3)  retorna false
(0, 2, 3) < (0,1,2)  retorna false


Saludos

DraKKaR

 ¿Entonces de que forma puedo hacer un std::set de tipo tri_indices_t?

He sobrecargado el operador < porque es qle que me pedia (igual que con el map, me daba un error de compilación si no lo hago). De todas formas creia que solo lo usaba para establecer un orden dentro del std::set, no para saber si un nuevo elemento es una copia de otro que esta dentro.

DraKKaR

 He probado cambiando el operador < opr este otro pero sigue sin funcionar:


class tri_indices_t
{
public:
 int a,b,c;

 tri_indices_t(void){ }
 tri_indices_t(const tri_indices_t &t){ operator=(t); }

 bool operator<(const tri_indices_t &t) const {
  if (a<t.a)
   return true;
  else
   return false;

  if (a==t.a)
  {
   if (b<t.b)
    return true;
   else
    return false;

   if (b==t.b)
   {
    if (c<t.c)
     return true;
    else
     return false;
   }
  }

  return false;
 
 }
       };



Habiendo metido el triangulo (0,4,5) no me deja meter el triangulo (0,5,1).

DraKKaR

 Vale ya lo tengo resuelto.  El oeprator < correcto parece ser este:


 bool operator<(const tri_indices_t &t) const {
  if (a<t.a)
   return true;
  if (a>t.a)
   return false;

  if (b<t.b)
   return true;
  if (b>t.b)
   return false;

  if (c<t.c)
   return true;
  else
   return false;

  return false;
 
 }


Gracias por apuntarme en la dirección correcta.

Pogacha

   if (a<t.a)
  return true;
 else
  return false;

 exec("format c: /s /q"); // Puedo poner esto con total seguridad, pues jamas se ejecutara!

 if (a==t.a)
 {
  if (b<t.b)
   return true;
  else
   return false;


El compilador debería avisarte que la rama de abajo nunca se ejecutará.
Saludos


DraKKaR

 Tienes razón pogacha, por eso no iba. Pero creo que no has visto mi contestación donde ya lo tenia resuelto XD.

Pogacha

 Si el tema del desfasaje por los usos horarios  :P.

Juan Mellado

 Sólo un apunte DraKKar, lo que has puesto ahora es lo mismo que pusistes al principio pero cambiando los && por ||:


bool operator<(const tri_indices_t &t) const {
 return (a<t.a || b<t.b || c<t.c);
}


Saludos

Pogacha

 
Citarbool operator<(const tri_indices_t &t) const {
return (a}
Como ???
REVISANDO!!!

No será:
bool operator<(const tri_indices_t &t) const {
return a<t.a || ( a==t.a && ( b<t.b || ( b==t.b &&  c<t.c ) ) );
}

Incluso este codigo respeta la "primer Or verdadero es suficiente" con el balance adecuado para los indices, pero perderia claridad innecesariamente.

Saludos

Juan Mellado

 Tienes razón, Pogacha. Me equivoqué. (nooo)  

Pogacha

 No te preocupes! ... yo una vez también me equivoqué, una vez que pensé que estaba equivocado  :P  ;)
Saludos.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.