Як працює метання та ловлення інтів?


14

З цим кодом:

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

Ми маємо:

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

Як працює catchблок читання , -1як int&? Ми не змогли призначити значення посиланню на значення, яке не має значення.

І чому друге std::coutтвердження виконується перед першим std::cerrтвердженням?


2
Ви впевнені, що це точний результат, який ви отримаєте? We caught an int exception with value: -1Лінія повинна бути надрукована першої.
HolyBlackCat

1
@Scheff, Вибачте, що ви праві, перший вихід переспрямований error streamне standard stream.
Ghasem Ramezani


2
@ FrançoisAndrieux Причиною цього є те, що відбувається різна семантика. Як правило, з тимчасовим ти не знаєш, що з ним станеться, тому було вирішено дозволити лише посилання const на тимчасові. За винятком, ми знаємо тривалість життя об'єкта і можемо захотіти його змінити і перекинути у вищий контекст. Для того, щоб полегшити це, стандарт дозволяє прив'язувати посилання на нецікаве значення.
NathanOliver

1
@ FrançoisAndrieux throwстворює копію (або переміщує) об’єкт, який ви передаєте йому. Посилання пов'язується з цією копією. Це має сенс, що копія є цінністю.
HolyBlackCat

Відповіді:


10

Це нормально через [крім.кидання] / 3

Закидання винятку копіює ініціалізує ([dcl.init], [class.copy.ctor]) тимчасовий об'єкт, який називається об'єктом виключення. Значення, що позначає тимчасовий, використовується для ініціалізації змінної, оголошеної у відповідному обробнику ([крім.handle]).

акцент мій

Як бачите, навіть якщо це тимчасовий характер, компілятор розглядає це як значення для ініціалізації обробника. Через це вам не потрібна посилання на const.


1
Але що з тим, в якому порядку відображаються повідомлення?
Томаш Зато -

8

З цієї throwдовідки :

На відміну від інших тимчасових об'єктів, об'єкт винятку вважається аргументом lvalue при ініціалізації параметрів запізнювання вилову, тому він може бути спійманий за допомогою посилання lvalue, модифікований та повторно скинутий.

Отже, хоча "об'єкт" тимчасовий, він все ще є цінністю, і як такий ви можете зловити його за посиланням.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.