Newsgroup: it.comp.lang.c++
Titolo: Templates ed azzeramento

Se creo il template di una classe che ovviamente può essere istanziata
per accettare diversi tipi di dati, ad esempio un b-tree che può
essere usato per memorizzare stringhe/interi/float ecc. ecc., come
azzero le variabili internet del tipo T se non so a priori di che tipo
sono?
Non so se mi sono spiegato o_O

 sono?
x=0;
E.

?manu* ha scritto:

Beh, per� per una stringa non ha senso. Ma a cosa ti serve "azzerare" i 
valori?
E.


Specializza il template per i tipi di base, e lascia la chiamata al
costruttore di default per tutti gli oggetti (anche string).
Specializzandolo per void* e poi con funzioni inline per T* chiamando
il template di void* puoi avere un unica istanza per tutti i puntatori
(cfr. Stroustrup).
In effetti però non so a cosa ti serva azzerare il tutto. Non ti basta
la costruzione per semplice dichiarazione di "T nomevar"?
Se vuoi "azzerare" un oggetto credo tu possa assegnargli una nuova
istanza, tipo "vecchiooggetto = T();"; un po' dispendioso ma
fattibile.
Matteo

Ma perchè, scusate, una variabile non inizializzata in modo esplicito
che valore possiede?
Io sono rimasto alla vecchia scuola per cui una variabile andrebbe
sempre inizializzata, ecco perchè chiedevo.
Non tanto per le stringhe, quando per i puntatori (li setto sempre a
NULL) e le variabili numeriche (che setto sempre a 0).
Però una variabile che non so a priori di che tipo sarà, mi chiedevo
come fare ad inizializzarla...

 come fare ad inizializzarla...
Se non sai con quale valore inizializzarla, come fa a esserti utile il 
fatto che sia inizializzata?
E.

 E.
Perchè voglio ke sia inizializzata a 0 se è un numero, a NULL se è un
puntatore...
Come tutte le cose che si inizializzano, non importa a quale valore,
purchè io possa contare sul fatto che, durante lo script, io sia certo
che ci sia _quel_ valore e non uno a caso.

 che ci sia _quel_ valore e non uno a caso.
A cosa ti serve sapere che c'� _quel_ valore?
E.

 puntatore...
Si fa cos�:
  template < class T >
   struct A 
   {       
           T m;
           A() : m() { }        
   };
Questo garantisce che anche i tipi built-in vengano inizializzati. 
Max

Max M. ha scritto:

A me il tuo esempio non funziona, la variabile m non viene inizializzata.
Invece cos� sembra funzionare, provato con int, char*, void* e std::string:
   template < class T >
    struct A
    {
            T m;
            A() { m = T(); }
    };

    };
Allora prova questa che dovrebbe essere meglio:
    template < class T >
     struct A
     {
             T m;
             A() : m(T()) { }
     };

 A me il tuo esempio non funziona, la variabile m non viene inizializzata.
Che compilatore usi? Non so bene che cosa dica lo Standard in proposito,
per� noto che l'implementazione di std::pair fornita con un GCC recente usa
la forma
  pair() : first(), second() { }
mentre quella fornita con un GCC *molto* vecchio usa
 pair() : first(_T1()), second(_T2()) {}
Quindi, non escludo si tratti di un comportamento modificato nell'ultima
revisione dello Standard (2003).
Max

 
Lo standard non l'ho letto, ma ho la vaga impressione che la prima forma 
sia quella giusta.
Peccato che con almeno un compilatore che conosco (che come ben sappiamo 
di standard ha ben poco: VC++6.0) non funziona. Mentre con VC++2008 
(notoriamente MOLTO aderente allo std) funziona.
La seconda forma funziona con entrambi.
Guardando l'implementazione di std::pair su MSVC (Plauger - Dinkumware) 
� nella seconda forma sia in VC++6.0 sia in VC++2008. Da cui deduco che 
sia comunque standard (e di fatto + portabile della prima)
Attenzione invece perch� un'espressione molto simile ma usata non nella 
init list ma nel codice ha un comportamento ben diverso:
struct S
{
  int a;
};
void foo()
{
  S x(S()); //1
  x.a = 3;  //2
}
Questo pezzo di codice NON dovrebbe compilare, ma con un errore "strano" 
nella linea //2 (il motivo � spiegato qu� 
http://parashift.com/c++-faq-lite/ctors.html#faq-10.19
 ) ma su VC++6.0 
compila e "funziona" come ci si potrebbe aspettare (con la riga //1 
viene creata una var. x di tipo S).
Ma in questi casi si dovrebbe usare:
void foo()
{
  S x = S();
}
hth.

Max M. ha scritto:

In effetti, non funziona su VC++6.0, mentre su VC++2005 e 2008 funziona.