2013-03-08 23 views
9

Ho un parametro enum in un programma C++ che ho bisogno di ottenere usando una funzione che restituisce il valore attraverso un parametro. Ho iniziato dichiarandolo come int ma alla revisione del codice è stato chiesto di digitarlo come enum (ControlSource). L'ho fatto ma interrompe la funzione Get(): ho notato che un cast di tipo C su int & risolve il problema, ma quando ho provato a risolverlo con un static_cast <> non è stato compilato.Perché non posso usare static_cast <int&> per passare un parametro di riferimento intero a una funzione in C++?

Perché è questo, e perché è che quando eTimeSource è stato un int non è richiesta alcuna trasmissione per passare l'intero per riferimento?

//GetCuePropertyValue signature is (int cueId, int propertyId, int& value); 

ControlSource eTimeSource = ControlSource::NoSource; 

pPlayback->GetCuePropertyValue(programmerIds.cueId, DEF_PLAYBACKCUEPROPERTY_DELAY_SOURCE, static_cast<int&>(eTimeSource)); //This doesn't work. 

pPlayback->GetCuePropertyValue(programmerIds.cueId, DEF_PLAYBACKCUEPROPERTY_DELAY_SOURCE, (int&)(eTimeSource)); //This does work. 

int nTimeSource = 0; 
pPlayback->GetCuePropertyValue(blah, blah, nTimeSource); //Works, but no (int&) needed... why? 
+0

"Opere, ma nessuna (int &) necessario ... perché?" - Dai un'occhiata alla documentazione del C++ riguardante il passaggio delle variabili per riferimento (o vedi qui: http://stackoverflow.com/a/410857/1174378) –

+0

Rimosso le parentesi doppie. Ho ragione nel presumere che il cast in stile C stia chiamando un reinterpret_cast su questo oggetto per farlo funzionare? Se è così, è davvero importante per un enum basato sul tipo int comunque? – Gareth

+0

No, 'reinterpret_cast' non è lo stesso di un cast di tipo" mazza ". Se hai bisogno di un brutto cast hacky per far funzionare il codice dopo aver cambiato il tipo, non cambiare il tipo! Funziona bene con 'int', non funziona OK con un enum ...sembra abbastanza chiaro quale sia la risposta per me –

risposta

8

Quando si converte una variabile a un valore di tipo diverso, si ottiene un valore temporaneo, che non può essere associato a un riferimento non costante: Non ha senso per modificare la temporanea.

Se avete solo bisogno di leggere il valore, un riferimento costante dovrebbe andare bene:

static_cast<int const &>(eTimeSource) 

Ma si potrebbe anche solo creare un valore reale, piuttosto che un punto di riferimento:

static_cast<int>(eTimeSource) 
+0

Nel cast di static_cast (eTimeSource) il compilatore mi dice che non è possibile trovare un overload appropriato della funzione e lo stesso vale per static_cast (eTimeSource). Non desidero veramente aggiornare la funzione GetProperty per prendere un riferimento const poiché sospetto che implichi l'esecuzione di molte modifiche altrove. – Gareth

+1

@Gareth: Quindi crea una variabile locale, 'int i = static_cast (eTimeSource);' e chiama la funzione con 'i'. –

+0

Abbastanza giusto - questo ovviamente funzionerebbe. È un po 'circolare tuttavia, come ho iniziato dichiarando la mia variabile come int in primo luogo, senza alcun cast, ma il recensore non gli piaceva! Vedo il suo punto: dichiarare correttamente il tipo rende chiaro a cosa serve, ma porta questo problema ... – Gareth

3
static_cast<int&>((eTimeSource))); //This doesn't work. 

destro, non funziona, perché non è un eTimeSourceint quindi non è possibile associare un int& ad esso.

(int&)((eTimeSource))); //This does work. 

Sbagliato, anche questo non funziona, sembra proprio. Il cast in stile C sta nel compilatore e dice "basta che lo faccia, anche se non è legale". Solo perché qualcosa compila non significa che funzioni.

perché è che quando eTimeSource era un int è necessaria alcuna colata affatto per passare il numero intero per riferimento?

Poiché è possibile associare un int& a un int ma non a un tipo diverso, e eTimeSource è un tipo diverso. Un int& è un riferimento a un int. Se fosse possibile associarlo a un tipo diverso, non si riferirebbe a uno int, vero?

Se il codice utente ha detto di cambiare la variabile a un tipo di enumerazione che probabilmente significava anche per voi di cambiare il parametro della funzione di prendere una ControlSource&

+0

Cosa succede se "ControlSource' è in realtà una' classe enum'? Dato il codice OPs, questa è un'opzione AFAICS ... –

+0

ControlSource è un enumerazione C++ nativa, non una classe enum o un enumerazione. Inoltre, il revisore non desiderava né si aspettava che il parametro passasse al tipo enum: la classe di archiviazione dati sottostante si basa sul valore digitato come int. È stato accettato che questo dovrebbe rimanere il caso (in quanto l'introduzione del tipo di enumerazione richiederebbe troppo tempo - non è banale come una firma delegata GetMethod più avanti sulla linea non può dire la differenza tra l'enum e l'int e ottiene il suo sovraccarichi in una torsione). Fare il lavoro di firma "corretta" non è compatibile con il tempo che ho a disposizione ATM! – Gareth

+0

@DanielFrey, cambierebbe qualcosa nella mia risposta? (TBH L'ho solo riletto brevemente, quindi se lo fa correggi) –