Newsgroup: it.comp.lang.c++
Titolo: const_cast per tipi complessi

Ho la seguente classe (presa dal libro di Struostrup)
template<class T> class Ptr
{
  private:
    T* p;
  public:
    Ptr(T* _p)
    : p(_p) {  }
    template<class T2> operator Ptr<T2>() { return Ptr<T2>(p); }
};
int main()
{
    Ptr<int> p(new int(77));
    Ptr<const int> cp(new int(99));
    Ptr<const int> cp2 = static_cast< Ptr<const int> >(p);   // ok
    Ptr<int> p2 = const_cast< Ptr<int> >(cp);     // errore
}
Con il BCC5.5 ottengo
Error E2031 template3.cpp 20: Cannot cast from 'Ptr<const int>' to 'Ptr<int>' in
 function main()
Warning W8004 template3.cpp 23: 'p2' is assigned a value that is never used in f
unction main()
*** 1 errors in Compile ***
mentre con il DJGPP
template3.cpp: In function `int main()':
template3.cpp:20: `Ptr<int>' is not a pointer, reference, or pointer-to-data-mem
ber type
template3.cpp:20: as required by const_cast
template3.cpp:20: const_cast from `Ptr<const int>' to `Ptr<int>'
Come faccio (e soprattutto è possibile) convertire un Ptr<const int> in un Ptr<int>?
(Ovviamente senza modificare la dichiarazione della class Ptr)
Grazie  Manlio Perillo

 Come faccio (e soprattutto è possibile) convertire un Ptr<const int> in un
Ptr<int>?
Sospetto che un reinterpret_cast te lo permetterebbe (eventualmente
un reinterpret_cast< Ptr<int>& >(cp2) a sinistra di un assignment,
se il tuo compilatore e` sufficientemente standard da ammetterlo).
Alex

 wrote in message 8l57t3$rom$5...@nslave1.tin.it...

E se aggiungessi una specializzazione parziale per Ptr<const T> in modo che
l'operatore di conversione in Ptr<T> usi const_cast?
E' fattibile?
(Con il BCC5.5 non mi è possibile, ma forse sbaglio la semantica).
Nota: con il BCC5.5 e DGJPP reinterpter_cast funziona.
Ma si comporta come const_cast o potrebbero sorgere problemi?
Grazie  Manlio Perillo

 Ma si comporta come const_cast o potrebbero sorgere problemi?
reinterpret_cast usa gli stessi identici bit di input come bit di
output.  Quindi, i problemi potrebbero sorgere eccome, tutte
le volte che l'identica bitpattern non sia quello che vuoi usare
come risultato.  Ad esempio, un reinterpret_cast<float> di un
long produce risultati diversi a seconda dell'esatta forma dei
numeri floating-point sulla macchina in questione.
Pero`, non conosco nessun compilatore che usi bit pattern
diverse per rappresentare puntatori allo stesso oggetto "visto
come const" e "visto come non-const".  Ne possono sicuramente
ESISTERE: un compilatore su di un'architettura segmentata
potrebbe, per aiutare il debugging, fare due segmenti per i dati,
identici in tutto e per tutto ma uno con attributi R/W e l'altro R/O,
cosi` che qualunque accesso errato garantisca immediata
eccezione.  E` solo che, al momento, non conosco nessuno che
in pratica usi approcci di questo tipo.
Alex

numeri floating-point sulla macchina in questione.
Con il BCC5.5 sia reinterpret_cast<int>(f) che
reinterpret_cast<float>(i) dove i e' un intero e f e' un
float non sono ammessi (Errore 2031). Anche VC++ non permette
la conversione perche' dice che la conversione e' implicita,
ottenibile con static_cast, con un C-style cast oppure con
int(f)/float(i) (Errore C2440).
In "The C++ programming language" si dice che si possono fare
poche assunzioni su cosa reinterpret_cast in realta' fa... ma
*spesso* il bit pattern non cambia.
Per fare cose di questo tipo io usavo in C l'espressione
*(int *)(&f) che e' traducibile in un equivalente C++ con
*reinterpret_cast<int *>(&f).
La mia impressione e' che reinterpret_cast sia ok per
puntatori/intero-abbastanza-lungo e viceversa o per conversioni
fra puntatori a cose non correlate (es. int/float), ma per ben
poco altro.
Si tratta di deviazioni dallo standard o e' corretto che
reinterpret_cast si rifiuti di convertire un int in un float ?
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff