Domanda

Qual è la differenza tra

(type)value

e

type(value)

in C ++?

È stato utile?

Soluzione

Non c'è differenza; secondo lo standard (§5.2.3):

Un identificatore di tipo semplice (7.1.5) seguito da un elenco di espressioni tra parentesi costruisce un valore del tipo specificato dato l'elenco di espressioni. Se l'elenco di espressioni è una singola espressione, l'espressione di conversione del tipo è equivalente (nella definizione e se definita nel significato) all'espressione di cast corrispondente (5.4).

Poiché la domanda specificava la differenza tra type (value) e (type) value , non c'è assolutamente alcuna differenza.

Se e solo se hai a che fare con un elenco separato da virgole di valori può esserci una differenza. In questo caso:

Se l'elenco di espressioni specifica più di un singolo valore, il tipo deve essere una classe con un costruttore adeguatamente dichiarato (8.5, 12.1) e l'espressione T (x1, x2, ...) è in effetti equivalente alla dichiarazione T t (x1, x2, ...); per alcune variabili temporanee inventate t, con il risultato è il valore di t come valore r.

Come sottolineato da Troubadour, ci sono alcuni nomi di tipi per i quali la versione type (value) semplicemente non verrà compilata. Ad esempio:

char *a = (char *)string;

verrà compilato, ma:

char *a = char *(string);

no. Lo stesso tipo con un nome diverso (ad esempio, creato con un typedef ) può funzionare però:

typedef char *char_ptr;

char *a = char_ptr(string);

Altri suggerimenti

Non c'è differenza; lo standard C ++ (edizioni 1998 e 2003) è chiaro su questo punto. Prova il seguente programma, assicurati di utilizzare un compilatore conforme, ad esempio l'anteprima gratuita all'indirizzo http://comeaucomputing.com/ tryitout / .

#include <cstdlib>
#include <string>
int main() {
  int('A'); (int) 'A'; // obvious
  (std::string) "abc"; // not so obvious
  unsigned(a_var) = 3; // see note below
  (long const&) a_var; // const or refs, which T(v) can't do
  return EXIT_SUCCESS;
}

Nota: unsigned (a_var) è diverso, ma mostra un modo in cui quei token esatti possono significare qualcos'altro. Dichiara una variabile denominata a_var di tipo unsigned e non è affatto un cast. (Se hai familiarità con i puntatori a funzioni o matrici, considera come utilizzare una parentesi attorno a p in un tipo come void (* pf) () o < code> int (* pa) [42] .)

(Gli avvisi sono prodotti poiché queste dichiarazioni non usano il valore e in un vero programma sarebbe quasi sicuramente un errore, ma tutto funziona ancora. Non ho avuto il coraggio di cambiarlo dopo aver fatto tutto in riga up.)

Non c'è alcuna differenza quando entrambi sono cast, ma a volte 'type (value)' non è un cast.

Ecco un esempio della bozza standard N3242, sezione 8.2.1:

struct S 
{
    S(int);
};

void foo(double a) 
{
    S w( int(a) ); // function declaration
    S y( (int)a ); // object declaration
}

In questo caso 'int (a)' non è un cast perché 'a' non è un valore, è un nome di parametro racchiuso tra parentesi ridondanti. Il documento afferma

  

L'ambiguità derivante dalla somiglianza tra uno stile di funzione   cast e una dichiarazione menzionata in 6.8 possono anche verificarsi nel contesto   di una dichiarazione. In quel contesto, la scelta è tra una funzione   dichiarazione con un set di parentesi ridondanti attorno a un parametro   nome e una dichiarazione di oggetto con un cast in stile funzione come   initializer. Proprio come per le ambiguità menzionate in 6.8, il   la risoluzione è quella di considerare qualsiasi costrutto che potrebbe essere un   dichiarazione una dichiarazione.

In c non esiste un tipo (valore) , mentre in c / c ++ sia tipo (valore) che (tipo) valore sono consentito.

Per illustrare le opzioni in C ++ (solo una ha un controllo di sicurezza)

#include<boost/numeric/conversion/cast.hpp> 

using std::cout;
using std::endl;
int main(){

    float smallf = 100.1;

    cout << (int)smallf << endl; // outputs 100 // c cast
    cout << int(smallf) << endl; // outputs 100 // c++ constructor = c cast

    cout << static_cast<int>(smallf) << endl; // outputs 100
//  cout << static_cast<int&>(smallf) << endl; // not allowed
    cout << reinterpret_cast<int&>(smallf) << endl; // outputs 1120416563
    cout << boost::numeric_cast<int>(smallf) << endl; // outputs 100

    float bigf = 1.23e12;

    cout << (int)bigf << endl; // outputs -2147483648
    cout << int(bigf) << endl; // outputs -2147483648

    cout << static_cast<int>(bigf) << endl; // outputs -2147483648
//  cout << static_cast<int&>(bigf) << endl; // not allowed
    cout << reinterpret_cast<int&>(bigf) << endl; // outputs 1401893083
    cout << boost::numeric_cast<int>(bigf) << endl; // throws bad numeric conversion
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top