2011-01-28 24 views
21

Sto scrivendo un'applicazione abbastanza semplice in C++ usando g ++ sotto Linux e sto provando a lanciare alcune stringhe come eccezioni (sì, lo so, non è una buona pratica).Che tipo dovrei prendere se lancio una stringa letterale?

Ho il codice seguente (semplificato):

int main() 
{ 
    try 
    { 
    throw "not implemented"; 

    } 
    catch(std::string &error) 
    { 
    cerr<<"Error: "<<error<<endl; 
    } 
    catch(char* error) 
    { 
    cerr<<"Error: "<<error<<endl; 
    } 
    catch(...) 
    { 
    cerr<<"Unknown error"<<endl; 
    } 
} 

e ottengo Unknow error sulla console. Ma se eseguo il cast statico della stringa letterale su std :: string o char *, stampa Error: not implemented come previsto. La mia domanda è: quindi qual è il tipo che dovrei prendere se non voglio usare i cast statici?

+0

Domanda stupida: qualcuno lancia cose che non ereditano da 'std :: exception' nel codice reale? (A parte il 'SuicideException', e no, non è derision: p) –

risposta

28

È necessario prenderlo con char const* anziché char*. Niente di simile a std::string o allo char* lo prenderà.

La cattura ha regole limitate per quanto riguarda i tipi corrispondenti. La specifica dice (dove "cv" significa "const/volatile combination" o nessuno dei due).

Un gestore è una corrispondenza per un oggetto eccezione di tipo E se

  • Il gestore è di tipo cv T o cv T & ed E e T sono dello stesso tipo (ignorando il primo livello cv-qualificatori) o
  • il conduttore di tipo cv T o cv T & e T è una classe base pubblica univoca di e o
  • il conduttore di tipo CV1 T * cv2 ed e è un puntatore digitare che può essere convertito nel tipo del gestore da o entrambi

    • una conversione puntatore standard (4.10) non prevedono conversioni a puntatori a privati ​​o classi ambigue protette o
    • una conversione qualifica

Una stringa letterale è di tipo char const[N] , ma il lancio di un array decomporrà l'array e in effetti genera un puntatore al suo primo elemento. Quindi non è possibile prendere una stringa letterale generata da un char*, perché al momento della corrispondenza, deve corrispondere allo char* a uno char const*, che getterebbe via un const (una conversione di qualifica è consentita solo a aggiungi const). La conversione speciale di una stringa letterale in char* viene considerata solo quando è necessario convertire in modo specifico una stringa letterale.

10

Prova ad aggiungere const ai tipi che stai catturando, const char* (possibilmente const char* const).

+2

' const char * 'funziona. http://ideone.com/6Fzid 'const std :: string &' no. –

+0

questo ha fatto il trucco! – Grzenio

+1

o il mio preferito personale: 'char const *' –

3

Il tipo esatto di stringa letterale è un array di caratteri const (const char [15] per l'esempio, poiché è incluso il terminatore NUL).

+0

quindi c'è qualche possibilità di catturarli tutti (per tutte le lunghezze)? – Grzenio

+3

L'array decade a 'const char *' quando viene lanciato. –

1

Il tipo deve essere const char[15] o const char*.

Tuttavia, mentre la lingua non vieta di lanciare alcun valore di tipo, non si devono sollevare tipi di dati nativi come eccezione.Invece, si desidera generare un'istanza std::exception() o creare la propria classe di eccezioni.

1

Il problema è che stai cercando di catturare qualcosa che è un const. Quanto segue funziona:

catch (const char * error) { cerr
1

Il tipo di una stringa letterale è char const *. Esiste una conversione (obsoleta) a char * fornita per compatibilità con il codice esistente a ritroso (ma è comunque necessario trattarla come const - qualsiasi tentativo di modifica fornisce UB).

Come tale, il codice come questo dovrebbe funzionare:

#include <iostream> 
using namespace std; 

int main() 
{ 
    try 
    { 
    throw "not implemented"; 

    } 
    catch(char const *error) 
    { 
    cerr<<"Error: "<<error<<endl; 
    } 
    return 0; 
} 
1

controllare la sezione 2.14.5 della dotazione di serie, si tratta tipi e generi di stringhe letterali su 3 pagine. Non fare ciò che hai iniziato a fare, basta dire:

throw std::exception("not implemented"); 

insieme a una corretta

catch (std::exception& pEx) 

C'è qualcosa di sbagliato in questo approccio "normale" ...?

+0

C'è qualcosa di sbagliato nel lanciare le stringhe? –

Problemi correlati