Che cos'è implicit_cast? quando dovrei preferire implicit_cast piuttosto che static_cast?Qual è la differenza tra static_cast e Implicit_cast?
risposta
Sto copiando da un commento che ho fatto a answer this comment in un altro posto.
È possibile eseguire il down-cast con
static_cast
. Non così conimplicit_cast
.static_cast
fondamentalmente consente di eseguire qualsiasi conversione implicita e inoltre il contrario di qualsiasi conversione implicita (fino ad alcuni limiti. Non è possibile downcast se è coinvolta una classe base virtuale). Maimplicit_cast
sarà solo accetta conversioni implicite. nessun down-cast, novoid*->T*
, nessunU->T
se T ha solo costruttori espliciti per U.
Si noti che è importante notare la differenza tra un cast e una conversione. Nel seguente cast non è attivo
int a = 3.4;
Ma una conversione implicita avviene da doppia a int. Cose come un "cast implicito" non esistono, dal momento che un cast è sempre una richiesta di conversione esplicita. Il nome costrutto per boost::implicit_cast
è una bella combinazione di "cast usando conversioni implicite". Ora l'intera implementazione di boost::implicit_cast
è questo (spiegato here):
template<typename T> struct identity { typedef T type; };
template<typename Dst> Dst implicit_cast(typename identity<Dst>::type t)
{ return t; }
L'idea è quella di utilizzare un contesto non dedotta per il parametro t
. Che evitare le insidie come la seguente:
call_const_version(implicit_cast(this)); // oops, wrong!
Ciò che è stato desiderato è quello di scrivere fuori come questo
call_const_version(implicit_cast<MyClass const*>(this)); // right!
il compilatore non può dedurre quale digitare il parametro di template Dst
dovrebbe nominare, perché prima deve sapere cosa è identity<Dst>
dato che fa parte del parametro utilizzato per la deduzione. Ma a sua volta dipende dal parametro Dst
(identity
potrebbe essere esplicitamente specializzato per alcuni tipi). Ora abbiamo una dipendenza circolare, per la quale lo Standard dice solo che un tale parametro è un contesto non dedotto, e deve essere fornito un esplicito argomento di template.
implicit_cast trasforma un tipo in un altro e può essere esteso scrivendo funzioni di cast implicite, per trasmettere da un tipo a un altro.
ad es.
int i = 100;
long l = i;
e
int i = 100;
long l = implicit_cast<long>(i);
sono esattamente lo stesso codice
tuttavia è possibile fornire i propri cast impliciti per i propri tipi, sovraccaricando implicit_cast come la seguente
template <typename T>
inline T implicit_cast (typename mpl::identity<T>::type x)
{
return x;
}
Vedi qui boost/implicit_cast.hpp Per ulteriori
Spero che questo aiuti
EDIT
Questa pagina parla anche implicit_cast New C++
Inoltre, la funzione primaria di static_cast è quello di eseguire un non modifica o trasformazione semantica da un tipo all'altro. Il tipo cambia ma i valori rimangono identici, ad es.
void *voidPtr = . . .
int* intPtr = static_cast<int*>(voidPtr);
voglio guardare a questo puntatore nullo, come se fosse un puntatore a int, il puntatore non cambia, e sotto le coperte voidptr ha esattamente lo stesso valore di intPtr. An implicit_cast, il tipo cambia ma anche i valori dopo la trasformazione possono essere differnet.
"_la funzione primaria di static_cast è eseguire una trasformazione non mutevole o semantica da un tipo all'altro.Il tipo cambia ma i valori rimangono identici_" in questo caso ('statico_cast
Le conversioni implicite, le conversioni esplicite e il static_cast sono tutte cose diverse. tuttavia, se è possibile convertire implicitamente, è possibile eseguire la conversione in modo esplicito e, se è possibile eseguire la conversione in modo esplicito, è possibile eseguire il cast in modo statico. Lo stesso nella direzione opposta non è vero, comunque. Esiste una relazione perfettamente ragionevole tra i cast impliciti e i cast statici . Il primo è un sottoinsieme del secondo.
Vedere sezione 5.2.9.3 del Visual C++ per dettagli
Altrimenti, un'espressione e può essere esplicitamente convertito in un tipo T utilizzando uno static_cast di Cast forma static_- (e) se la dichiarazione T t (e); è ben formato, per alcuni inventato variabile temporanea t (8.5).
C++ incoraggia l'uso di static_casts perché rende la conversione "visibile" nel programma. L'uso di cast in sé indica una regola imposta dal programmatore che vale la pena di guardare in modo da utilizzare meglio static_cast.
Preferire implcit_cast se è sufficiente nella situazione.implicit_cast è meno potente e più sicuro di static_cast.
Ad esempio, downcasting da un puntatore di base a un puntatore derivato è possibile con static_cast ma non con implicit_cast. Il contrario è possibile con entrambi i calchi. Quindi, quando passi da una base a una classe derivata, usa implicit_cast, perché ti tiene al sicuro se confondi entrambe le classi.
Inoltre, tenere presente che implicit_cast spesso non è necessario. L'uso del no cast funziona quasi sempre quando implicit_cast lo fa, da qui deriva "implicito". implicit_cast è necessario solo in circostanze particolari in cui il tipo di un'espressione deve essere esattamente controllato, ad esempio per evitare un sovraccarico.
Hai" derivato "e" base "all'indietro qui. Un puntatore derivato può sempre essere convertito in una base (pubblica o accessibile), ma la conversione in down richiede un cast esplicito. –
@ AdamH.Peterson Hai ragione. Ho appena modificato la risposta. –
Nel caso in cui si stia chiedendo di abt boost :: implicit_cast; per favore modifica il post per dirlo in modo più chiaro. – Abhay
@Abhay Il concetto di 'implicit_cast' è molto più vecchio di Boost - molti anni più vecchio. – curiousguy
@curiousguy: cose come un "cast implicito" non esistono, dal momento che un cast è sempre una richiesta di conversione esplicita. Leggi la risposta accettata per i dettagli ... – Abhay