2011-10-21 12 views
6

Ho un problema che quando uso qualcosa di simile:Come restituire "non trovato" quando il valore di ritorno è di riferimento const

const MyList& my_list = getListForThisRegion(/*region ID, ...*/); 

non so cosa per tornare quando viene trovato nessun valore.

Il mio problema è che mi piacerebbe avere un modo per segnalare (quando si restituisce il valore da getListForThisRegion) "valore non trovato" al chiamante. Se dovessi restituire un puntatore, potrei restituire nullptr, ma non so come farlo con i riferimenti. Tutto quello che posso pensare è avere un membro statico not_found di tipo MyList e restituire un riferimento ad esso, ma sembra brutto.

E sì, non posso restituire il valore perché le liste sono "grasse" e spesso utilizzate.

MODIFICA: tonnellate di grandi risposte, ma l'eccezione non è una soluzione accettabile in quanto il numero di volte in cui viene generato è elevato (la percentuale nbNotFound/nbCalls è alta).
EDIT2: per quanto riguarda boost :: opzionale - quanto è complicato padroneggiare? Voglio dire richiede qualche conoscenza non ovvia (non ovvio = qualcosa che non è semplicemente conoscendo la sintassi)?

+3

lanciare un'eccezione può essere una buona opzione. – BigMike

+1

potresti anche voler dare un'occhiata a 'boost :: optional' – Akanksh

+0

Un riferimento deve fare riferimento a un oggetto, in modo da lanciare un'eccezione o non utilizzare un riferimento. 'boost :: optional' è un'ottima scelta, ma potrebbe essere eccessivo; basta usare un puntatore. – GManNickG

risposta

7

Ci sono due modi per gestire questo idiomatiche:

  • cambiare la vostra interfaccia per restituire un tipo che ha la capacità di fare riferimento a nulla (per esempio un puntatore che può essere nullo, un iteratore per end).

O

  • un'eccezione se l'oggetto non viene trovato.

Restituzione di un oggetto fittizio è un po 'hacky, e non si guadagna nulla nel corso di restituire un puntatore come si devono ancora verificare il risultato contro un valore speciale (null o l'oggetto fittizio).

+3

'boost :: facoltativo 'è un buon tipo qui. –

+0

@ edA-qamort-ora-y: ciò cambierebbe la semantica per restituire per valore anziché per riferimento (a meno che non si restituisca un riferimento facoltativo, ma non vedo cosa ciò aggiunge a un puntatore). –

+0

@Mike: Che ne dite di 'boost :: optional >'? – fredoverflow

1

Scriverei una classe di eccezioni (gerarchia, se necessario) e generare un'eccezione per tale caso.

1

Vedo solo due possibilità: o si dispone di un membro speciale nella classe MyList che dichiara che un'istanza è "null" (non impostata) o si potrebbe generare un'eccezione.

+1

Avere un membro in 'MyList' per indicare che il valore nullo sembra molto invadente. Questo tipo di funzionalità è spesso meglio ottenuto avvolgendo l'oggetto in un altro. 'Boost.Optional ' fornisce tale wrapper per rappresentare un oggetto nullable. –

1

È possibile seguire il comando std::map e inserire un elenco predefinito predefinito nel contenitore e restituire un riferimento. Ovviamente, questo dipende dal fatto che non ci sia una differenza semantica tra una lista di default e una lista che non c'è affatto.

È inoltre possibile aggiungere una funzione di query che cerca una determinata regione e restituisce true se ha una lista e false altrimenti. Quindi, puoi lanciare un'eccezione nella tua accessor sicura sapendo che non sarà un evento comune.

3

Come su riscrivere la funzione per fare riferimento a "returnValue" in cui si inserisce l'elenco per restituire? Quindi la funzione può restituire il valore booleano che indica trovato/non trovato.

bool getListForThisRegion(/*region ID, ...*/, MyList& ret_list); 
Problemi correlati