Newsgroup: it.comp.lang.c++
Titolo: Problema con i puntatori a void

Devo scrivere una funzione che mi stampi un oggetto passato come parametro,
senza conoscere di quale tipo sia l'oggetto.
Avevo pensato di utilizzare un puntatore a void, ma prima di essere
dereferenziato, deve essere convertito esplicitamente al tipo opportuno
(cast).
Guardate il seguente esempio:
#include <iostream>
#include <string>
using namespace std;
void stampa (void* p)
{
 cout << *p << endl;    // Error: illegal indirection
 // Ci vorrebbe cout << *(int*)p << endl;    // Ma non conosco il tipo
esplicito a priori
 [...]
}
int main()
{
 int i = 5; int* pi = &i;
 char c = 'd'; char* pc = &c;
 string s = "prova di stringa"; string* ps = &s;
 stampa (pi);
 stampa (pc);
 stampa (ps);
 return 0;
}
Vorrei utilizzare questo stratagemma per scrivere il file di log, che
registra tutti gli eventi durante l'esecuzione di un algoritmo. Infatti
vorrei scrivere una classe Output con una funzione che scrive in un file
delle informazioni (stringhe, vettori, interi,...) ogni volta che viene
invocata.
Per ora ho messo lo stream pubblico:
class Output
{
 public:
 Output ();
 fstream logFile;    // File di log
};
Ma cercavo una soluzione + elegante.
~~~~~~~~~~~~~~~~~~~~~~
Leonardo Anceschi
rimuovi .no.spam dall'indirizzo
~~~~~~~~~~~~~~~~~~~~~~

 }
template<typename T> void stampa(T* p)
{
    cout  << *p << endl;
}
A tal proposito, che differenza c'è tra:
template<typename T> void stampa(T* p)
e
template<class T> void stampa(T* p)
?
--
Gerolamo

 template<class T> void stampa(T* p)
Pigi meno tasti.
I piu' sofisticati usano 'class' per indicare che il template accetta 
solo tipi definiti dall'utente.
Ciao,
Nicola

 solo tipi definiti dall'utente.
Non è vero, questo codice compila perfettamente senza che io abbia mai 
definito int:
#include <iostream>
using namespace std;
template <class T>
void print (T x)
{
        cout << x << endl;
}
int main ()
{
        print<int> (3);
        return 0;
}
-- 
Andrea Bergia - studente          Linux Registred User #281550
Per favore non mandatemi allegati in Word o PowerPoint.
Si veda 
http://www.fsf.org/philosophy/no-word-attachments.html


Saluti
Rosario Ianuale

 (cast).
In C++ i puntatori a void servono solo in casi molto rari, di solito
ci sono soluzioni piu` semplici e sicure.
        Mauro

   }
Piccolo errore: template <typename T> void stampa (const T& oggetto)
Ovvero: il const va prima del tipo.


 Ovvero: il const va prima del tipo.
E` la stessa cosa.
Nel caso di puntatori il const si riferisce a quello che c'e` alla sua
sinistra:
  int *                 puntatore a intero
  int * const           puntatore costante a intero
  int const *           puntatore a intero costante
  int const * const     puntatore costante a intero costante
  int * const *         puntatore a puntatore costante a intero
Il const all'inizio si riferisce al primo elemento:
  const int *           = int const *
  const int * const     = int const * const
Per un tipo semplice T const e const T sono equivalenti.
        Mauro

 }
Anche senza indicare <int> nella chiamata a funzione,
poichè il compilatore lo ricava automaticamente dal tipo
del parametro passato.
int main ()
{
        print(3);
        return 0;
}
--
Gerolamo

 definito int:
Nicola parlava di una sorta di convezione non ufficiale che si sta
diffondendo. 'class' e 'typename' in quel contesto sono perfettamente
equivalenti, ma alcuni ("i più sofisticati") hanno l'abitudine di usare
'typename' nei casi più generici, e 'class' nei casi in cui si sa che
l'argomento non può essere un tipo built-in.
Max

Grazie!


 del parametro passato.
Lo so. Volevo evidenziare che anche per un tipo "built-in" funziona 
benissimo.
