Domanda

So che l'operatore ternario ha alcune restrizioni sorprendenti, ma ero un po 'sconcertato che questo non riesce a compilare per me:

void foo(bool b)
{
    int* ptr =  ((b) ? NULL : NULL);
}

Ovviamente questo è il minimo necessario per mostrare il problema. L'errore è:

[BCC32 Error] Unit11.cpp(20): E2034 Cannot convert 'int' to 'int *'

Compiler è la meno-che-100% -conformi Embarcadero C ++ Builder 2010, quindi un errore del compilatore è tutt'altro che impossibile ...

NOTA: Parens modificato in modo da evitare confusione circa il mio intento

.

Nota 2: avrei ottenuto io stesso un po 'confuso su come ero arrivato a questo costrutto, in primo luogo, quindi ecco la mia scusa: mi è stato sempre alcuni errori di compilazione su una linea come a = b? c : d, dove b, c, d erano tutte espressioni complesse. Per restringere il campo, ho sostituito c e d con NULLs al fine di verificare se b era il colpevole. A questo punto, tutto è andato all'inferno in un carretto a mano.

È stato utile?

Soluzione

NULL è una macro che si espande per 0 (o qualche espressione costante solidale ad un valore di 0, per esempio, (1 - 1)). Non è altrimenti "speciale".

Qualunque costante espressione solidale ad un valore di zero è utilizzabile come puntatore nullo costante, che è la ragione che int* ptr = 0; è consentito. Tuttavia, qui, l'espressione è b ? 0 : 0; questo non è un'espressione costante intera (b non è costante); il suo tipo è int, che non è implicitamente convertibile in int*

La soluzione sarebbe quella di specificare in modo esplicito che si desidera un tipo di puntatore:

int* const null_int_ptr = 0;
int* ptr = b ? null_int_ptr : null_int_ptr;

L'esempio è un po 'artificiosa, però: di solito quando si usa l'operatore condizionale, almeno uno degli argomenti è in realtà un tipo di puntatore (ad esempio b ? ptr : 0); quando uno degli operandi è un tipo di puntatore, il 0 viene convertito implicitamente a quello stesso tipo puntatore e quindi il tipo dell'intera espressione condizionale è il tipo di puntatore, non int.

L'unico caso in cui si può avere questo "problema" è dove un puntatore nullo costante viene utilizzata sia come secondo e terzo operandi dell'operatore condizionale, che è piuttosto dispari.

Altri suggerimenti

Il tuo problema è che sul sistema NULL è definito come 0, che si presume essere un int nel contesto l'operatore ternario. Se si static_cast uno degli operandi per int* si dovrebbe auto-promuovere l'altro.

Ma perché si utilizza un tale costrutto, in primo luogo?

NULL potrebbe essere definito come avente tipo int o anche long, quindi l'operatore ternario ha lo stesso tipo. Non c'è alcuna conversione implicita al tipo di puntatore, in modo compilatore genera un errore. Il Gotcha ecco che esiste una conversione implicita da costante espressione intera valutare a zero (il famigerato puntatore nullo costante).

Possibile soluzione qui è un cast esplicito:

int* ptr =  b ? (int*) NULL : NULL;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top