Come funzionano i tiri e le prese?


14

Con questo codice:

int main()
{
    try
    {
        throw -1;
    }
    catch (int& x)
    {
        std::cerr << "We caught an int exception with value: " << x << std::endl;
    }
    std::cout << "Continuing on our merry way." << std::endl;

    return 0;
}

Abbiamo:

/tmp$ ./prorgam.out
Continuing on our merry way
We caught an int exception with value: -1

Come funziona il catchblocco di legge -1come int&? Non è stato possibile assegnare un valore a un riferimento al valore non costante.

E perché la seconda std::coutistruzione viene eseguita prima della prima std::cerr?


2
Sei sicuro che questo sia l'output esatto che ottieni? La We caught an int exception with value: -1riga deve essere stampata per prima.
HolyBlackCat

1
@Scheff, mi spiace hai ragione, il primo output viene reindirizzato a error streamnon standard stream.
Ghasem Ramezani,


2
@ FrançoisAndrieux Il motivo per cui è consentito è che ci sono diverse semantiche in corso. Generalmente con un temporaneo non sai cosa gli succederà, quindi è stato deciso di consentire solo riferimenti costanti ai provvisori. Con le eccezioni, conosciamo la durata dell'oggetto e potremmo volerlo modificare e riproporlo in un contesto più elevato. Per facilitare ciò, lo standard consente l'associazione a un riferimento di valore non costante.
NathanOliver,

1
@ FrançoisAndrieux throwcrea una copia (o sposta) l'oggetto che gli viene passato. Il riferimento si lega a quella copia. In un certo senso ha senso che la copia sia un valore.
HolyBlackCat

Risposte:


10

Questo va bene a causa di [excluded.throw] / 3

Il lancio di un'eccezione copia-inizializza ([dcl.init], [class.copy.ctor]) un oggetto temporaneo, chiamato oggetto eccezione. Un valore che indica il temporaneo viene utilizzato per inizializzare la variabile dichiarata nel gestore corrispondente ([tranne.handle]).

enfatizzare il mio

Come puoi vedere, anche se è temporaneo, il compilatore lo considera come un valore per l'inizializzazione del gestore. Per questo motivo, non è necessario un riferimento const.


1
Ma cosa succede con l'ordine in cui appaiono i messaggi?
Tomáš Zato - Ripristina Monica il

8

Da questo throwriferimento :

A differenza di altri oggetti temporanei, l'oggetto eccezione è considerato un argomento lvalue quando si inizializzano i parametri della clausola catch, quindi può essere catturato dal riferimento lvalue, modificato e riproposto.

Quindi, mentre "l'oggetto" è temporaneo, è ancora un valore e come tale puoi prenderlo come riferimento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.