2012-03-03 32 views
7

Sto solo imparando C++ e vorrei lanciare un'eccezione, ma il risultato della mia funzione sarebbe indefinito ???Eliminare l'eccezione e restituire il risultato di una funzione

std::vector<myStruct> extract_notworking(std::vector<myStruct>& avec){ 
     std::vector<myStruct> result; 

     if (avec.size() == 0) 
      //throw domain_error("Cannot operate on empty vector!"); 
      //Cannot use exception for it would yield undefined result 
      return result; 

     //do something here 
     //... 
     return result; 
    } 

Cosa devo fare? Restituire un vettore vuoto? Cosa accadrebbe se lanciassi l'eccezione al destinatario del valore restituito?

+8

Se si genera un'eccezione, la funzione non viene restituita. Questo è il punto. –

+0

Quindi forse rendere la mia funzione nullo e aggiungere un altro parametro facendo riferimento al mio vettore? – Mihaela

+1

possibile duplicato di [Ritorno dopo aver generato eccezioni] (http://stackoverflow.com/questions/3109943/returning-after-throwing-exceptions) –

risposta

9

Quando si genera un'eccezione, la funzione si ferma lì e l'esecuzione salta ovunque sia stata rilevata l'eccezione. La tua funzione non restituisce nulla perché la funzione non ritorna affatto.

Si può solo fare

if (avec.empty()) 
    throw domain_error("Cannot operate on empty vector!"); 

E la funzione si esce lì.

Nota che non è necessario preoccuparsi del valore restituito ("Come può una funzione non restituire nulla?" Ecc.) Perché non è possibile accedere al valore restituito di una funzione che ha gettato (e non ha catturato) un'eccezione anche se provi.

Così, per esempio, se si fa

try { 
    std::vector<myStruct> vec; 

    std::vector<myStruct> retval = extract_notworking(vec); 

    print_vector(retval); // this line is only executed if extract_networking 
          // does not throw an exception 
} catch (const domain_error& e) { 
    // we can't access retval here so no worries 
} 

è possibile accedere solo retval se la funzione restituisce correttamente (vale a dire non buttare). Nell'esempio, la tua funzione verrà generata perché vec è vuoto, quindi print_vector non verrà mai chiamato.

Anche se si esegue questa operazione:

std::vector<myStruct> retval; 

try { 
    std::vector<myStruct> vec; 

    retval = extract_notworking(vec); 

    print_vector(retval); 
} catch (const domain_error& e) { 
    // we can access retval here but the assignment never happened 
} 

Poiché la funzione non ha restituito, l'assegnazione del suo valore di ritorno di retval non è successo, e retval è ancora perfettamente normale default-costruito vector che possono usare liberamente. In questo esempio, retval non è assegnato a e retval non viene stampato, perché extract_networking ha generato un'eccezione e l'esecuzione è saltata nel blocco catch prima che queste due cose potessero accadere.

+0

Grazie, lancerò l'eccezione e la prenderò nel chiamante. – Mihaela

1

Cosa devo fare? Restituire un vettore vuoto? Cosa accadrebbe se lanciassi l'eccezione al destinatario del valore restituito?

Ciò che viene restituito da una funzione è irrilevante, poiché il valore restituito non verrà utilizzato in alcun modo. L'esecuzione continuerà alla prossima cattura per quella particolare eccezione (fuori rotta dopo aver srotolato lo stack).

4

Quando si è throw un'eccezione, non è possibile return e viceversa. È possibile pensare alle eccezioni come un return generalizzato progettato per circostanze ed errori eccezionali.Considerate questa funzione:

int f(bool b) { 
    if (b) 
     return 42; 
    throw std::runtime_error("Runtime error!"); 
} 

Quando lo chiamiamo noi, siamo in grado di catturare il suo normale valore di ritorno (in questo caso un int) in un'espressione, o siamo in grado di catturare il suo eccezionale valore di ritorno (std::runtime_error) utilizzando un blocco try con catch del tipo corretto:

try { 

    int normal_result = f(b); 

    // Use normal result. 
    // (Exceptional result does not exist.) 
    std::cout << normal_result << '\n'; 

} catch (const std::exception& exceptional_result) { 

    // Use exceptional result. 
    // (Normal result does not exist.) 
    std::cout << exceptional_result.what() << '\n'; 

} 

il potere di eccezioni, naturalmente, deriva dal fatto che si propagano lo stack di chiamate fino a raggiungere una stuoia ching catch. In questo modo è possibile utilizzarli per evadere da chiamate di funzioni profondamente nidificate, garantendo al contempo che le risorse (memoria, file, & c.) Siano gestite correttamente.

Problemi correlati