Bagaimana cara melempar dan menangkap barang?

14

Dengan kode ini:

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;
}

Kita punya:

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

Bagaimana catchblok membaca -1sebagai int&? Kami tidak dapat menetapkan nilai ke referensi nilai non-konstanta.

Dan mengapa yang kedua std::cout pernyataan dieksekusi sebelum std::cerrpernyataan pertama ?

Ghasem Ramezani
sumber
2
Apakah Anda yakin ini adalah output tepat yang Anda dapatkan? The We caught an int exception with value: -1garis harus dicetak pertama.
HolyBlackCat
1
@ Steff, Maaf Anda benar, Output pertama diarahkan ke error streamtidak standard stream.
Ghasem Ramezani
2
@ FrançoisAndrieux Alasannya diizinkan adalah ada semantik berbeda yang terjadi. Umumnya dengan sementara Anda tidak tahu apa yang akan terjadi padanya sehingga diputuskan untuk hanya memperbolehkan referensi const untuk sementara. Dengan pengecualian, kita tahu masa pakai objek dan kita mungkin ingin memodifikasinya dan mengolahnya kembali ke konteks yang lebih tinggi. Untuk memfasilitasi itu, standar memperbolehkan pengikatan pada referensi nilai yang tidak konstan.
NathanOliver
1
@ FrançoisAndrieux throwmembuat salinan (atau memindahkan) objek yang Anda lewatkan. Referensi mengikat salinan itu. Agak masuk akal bahwa salinan tersebut merupakan nilai tambah.
HolyBlackCat

Jawaban:

10

Ini tidak apa-apa karena [exception.throw] / 3

Melempar eksepsi-inisialisasi salin ([dcl.init], [class.copy.ctor]) objek sementara, disebut objek pengecualian. Nilai yang menunjukkan temporer digunakan untuk menginisialisasi variabel yang dideklarasikan dalam handler yang cocok ([kecuali. Menangani]).

penekanan milikku

Seperti yang Anda lihat, meskipun bersifat sementara, kompiler memperlakukannya sebagai nilai untuk menginisialisasi pawang. Karena itu, Anda tidak perlu referensi const.

NathanOliver
sumber
1
Tapi bagaimana dengan urutan pesan itu muncul?
Tomáš Zato - Reinstate Monica
8

Dari referensi inithrow :

Tidak seperti objek sementara lainnya, objek pengecualian dianggap sebagai argumen nilai ketika menginisialisasi parameter klausa tangkapan, sehingga dapat ditangkap oleh referensi nilai, dimodifikasi, dan rethrown.

Jadi sementara "objek" bersifat sementara, itu masih bernilai tinggi dan dengan demikian Anda dapat menangkapnya dengan referensi.

Beberapa programmer Bung
sumber