Newsgroup: it.comp.lang.c++
Titolo: Confronto di strutture

Salve a tutti,
ho delle strutture con molti campi e ogni struttura
ha un metodo "!=" per confrontarle (tra quelle dello stesso tipo 
ovviamente) come posso eseguire un confronto che non sia campo a 
campo ? avete qualche alternativa alla memcmp ?
vi ringrazio.
-- 
Inviato da Virgilio 
http://newsgroup.virgilio.it
Filtra gli antipatici, segnala le risposte, segue i thread, e tutto da web

 campo ? avete qualche alternativa alla memcmp ?
Dipende da quello che vuoi ottenere. Cosa rende due strutture "diverse"?
Per esempio potresti anche stabilire che due strutture sono diverse se
non sono la medesima struttura (la stessa area di memoria intendo).
Oppure che alcuni campi possono essere legittimamente diversi ma che per
te le due istanze sono comunque uguali.
Dicci cosa intendi per "diverse".
-- 
[ RiK0                                ]
[ Go away! The internet is full!      ]
[ Non credo negli schemi non vincenti ]

 campo ? avete qualche alternativa alla memcmp ?
Non e' chiaro il problema...
Se hai delle strutture molto grosse e potrebbe essere inefficiente il
confronto campo a campo (specie se da fare molto di frequente) puoi
aggiungere un hash della struttura (da aggiornare alla fine di ogni
metodo non const) e, dell'operatore di confronto controlla prima gli
hash, e confronta i campi solo se gli hash coincidono.
Puoi anche fattorizzare la gestione dell' hash in una classe base e
derivare le tue struct da essa:
class HashedStruct {
    int32 hash_;
protected:
   // da implementare nelle classi concrete
   // esegue la costosa operazione di confronto
   virtual bool Compare(const HashedStruct &other) const = 0;
   // da implementare nelle classi concrete
   // calcola l'hash della classe
   virtual int ComputeHash() const = 0;
   // da chiamare in fondo ad ogni metodo pubblico non const
   // della classe concreta
   void UpdateHash() { hash_ = ComputeHash(); }
public:
  virtual ~HashedStruct() {}
  bool operator ==(const HashedStruct &other) const {
    if (hash_ != other,hash_) return false;
    return Compare(other);
  }
  bool operator !=(const HashedStruct &other) const {
   return ! ( *this == other );
  }
};
Saluti,
Fabio


Ciao,
è solo una curiosità: cosa non ti piace della memcmp? Se è perché a volte 
non funziona allora la domanda diventa: hai dichiarato la struttura tra le 
direttive di precompilazione ...
#pragma pack(1)
.
.
.
#pragma pack()
?
Un saluto. 

Scusa, una dimanticanza ... e la memset delle stringhe per la loro 
dimensione prima del loro utilizzo. 

 è solo una curiosità: cosa non ti piace della memcmp?
Se la struttura contiene campi non "banali" (per esempio stringhe)
la memcmp non va bene.
Fabio

Se la struttura contiene campi non "banali" (per esempio stringhe)
la memcmp non va bene.
Fabio
Ciao Fabio,
lo avevo scritto subito sotto il mio post. Se le memsetti par tutta la loro 
lunghezza si può fare a patto che nella struttura non vi siano puntatori di 
alcun tipo. Se non prendo cantonate, lo spazio in memoria dove viene 
allocata una struttura contenente delle stringhe è contiguo e comprensivo 
dello spazio delle stringhe. Il problema è che il prossimo scrittore del 
prossimo compilatore potrebbe decidere di gestire le stringhe nelle 
strutture in modo diverso.
Un saluto. 

 alcun tipo.
Che vuol dire "memsetti" ??
Esempio:
struct A {
  std::string s;
};
A x1;
A x2;
x1.s = "prova"
x2 = x1;
assert( x1 == x2 );
assert( memcmp( (void *) &x1, (void *) &x2,  sizeof(A) ) );
Le strutture sono uguali (campo a campo) ma non per la memcmp().
Fabio

 Le strutture sono uguali (campo a campo) ma non per la memcmp().
Così dovrebbe funzionare. 

Mi spiego meglio,
// myStr è una struttura che contiene campi tipo 
// int, float, double ....
myStr str1, str2;
str1 = ......;
str2 = ......; 
il mio problema è che se faccio la memcmp e un campo 
float ( o double ) cambia di pochissimo (pochissimo per 
me potrebbe anche andar bene) la memcmp fallisce. 
Cercavo un metodi più sofisticato.
Idee ?
P.S.: Io una idea l'ho quasi partorita, appena ho chiarito 
che cosa ho nella zucca ve lo scrivo .


 Idee ?
Potresti scrivere una funzione apposita per confrontare double/float
che ritorni true se la differenza dei due valori e' minore di un
epsilon abbastanza piccolo (per generalita' epsilon dovrebbe dipendere
dal valore assoluto dei due operandi, in base alla precisione
desiderata).
Nell'operatore di confronto per le tue struct usi quella funzione per
confrontare i numeri in virgola mobile e l'operatore uguale per gli
altri membri.
HTH,
Fabio