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.
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
¿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.
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).
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.
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
Tienes razón pogacha, por eso no iba. Pero creo que no has visto mi contestación donde ya lo tenia resuelto XD.
Si el tema del desfasaje por los usos horarios :P.
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
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
Tienes razón, Pogacha. Me equivoqué. (nooo)
No te preocupes! ... yo una vez también me equivoqué, una vez que pensé que estaba equivocado :P ;)
Saludos.