Сообщение Re: Потрея типа исключения от 25.08.2014 8:17
Изменено 25.08.2014 8:20 Кодт
Здравствуйте, ML380, Вы писали:
ML>Будет ли в данном случае потерян тип исключения при последующей ловле?
Будет, потому что throw кидает значение. Произойдёт банальное копирование со срезкой.
ML>Есть ли отличия данноного кода от просто "throw"?
Собственно, вот они и есть. "просто throw" продолжает работать со старым экземпляром, что позволяет делать, например, такой диспетчер исключений.
В противном случае пришлось бы вывернуть код наизнанку, прибегнув к функциям (или макросам) высшего порядка
ML>Будет ли в данном случае потерян тип исключения при последующей ловле?
Будет, потому что throw кидает значение. Произойдёт банальное копирование со срезкой.
ML>Есть ли отличия данноного кода от просто "throw"?
Собственно, вот они и есть. "просто throw" продолжает работать со старым экземпляром, что позволяет делать, например, такой диспетчер исключений.
void detailed_panic()
{
try { throw; } // запускаем сопоставление типа
catch(Foo const& e) { ..... }
catch(Bar const& e) { ..... }
.....
// если дефолтная ветка catch(...) ничего содержательного не делает, можно её не писать
// из любой ветки можно пробросить исключение выше-дальше с помощью throw;
// или бросить новое ислючение throw Xyz(......);
}
void alfa(.....)
{
try { ..... } // делаем что-то полезное
catch(...) { detailed_panic(); }
}
void beta(.....)
{
try { ..... }
catch(...) { detailed_panic(); } // повторно используем код обработки
}
В противном случае пришлось бы вывернуть код наизнанку, прибегнув к функциям (или макросам) высшего порядка
template<class Fun> void run_and_catch(Fun&& fun)
{
try { fun(); }
catch(Foo const& e) { ..... }
catch(Bar const& e) { ..... }
.....
}
void alfa(.....)
{
run_and_catch( [&]() { ..... } );
}
// или, по старому стилю,
void beta_impl(.....) { ..... }
void beta()
{
run_and_catch( boost::bind(beta_impl, .....) );
}
Re: Потрея типа исключения
Здравствуйте, ML380, Вы писали:
ML>Будет ли в данном случае потерян тип исключения при последующей ловле?
Будет, потому что throw кидает значение. Произойдёт банальное копирование со срезкой.
ML>Есть ли отличия данноного кода от просто "throw"?
Собственно, вот они и есть. "просто throw" продолжает работать со старым экземпляром, что позволяет делать, например, такой диспетчер исключений.
В противном случае пришлось бы вывернуть код наизнанку, прибегнув к функциям (или макросам) высшего порядка
ML>Будет ли в данном случае потерян тип исключения при последующей ловле?
Будет, потому что throw кидает значение. Произойдёт банальное копирование со срезкой.
ML>Есть ли отличия данноного кода от просто "throw"?
Собственно, вот они и есть. "просто throw" продолжает работать со старым экземпляром, что позволяет делать, например, такой диспетчер исключений.
void detailed_panic()
{
try { throw; } // запускаем сопоставление типа
catch(Foo const& e) { ..... }
catch(Bar const& e) { ..... }
.....
// если дефолтная ветка catch(...) ничего содержательного не делает, можно её не писать
// из любой ветки можно пробросить исключение выше-дальше с помощью throw;
// или бросить новое ислючение throw Xyz(......);
}
void alfa(.....)
{
try { ..... } // делаем что-то полезное
catch(...) { detailed_panic(); }
}
void beta(.....)
{
try { ..... }
catch(...) { detailed_panic(); } // повторно используем код обработки
}
В противном случае пришлось бы вывернуть код наизнанку, прибегнув к функциям (или макросам) высшего порядка
template<class Fun> void run_and_catch(Fun&& fun)
{
try { fun(); }
catch(Foo const& e) { ..... }
catch(Bar const& e) { ..... }
.....
}
void alfa(.....)
{
run_and_catch( [&]() { ..... } );
}
// или, по старому стилю,
void beta_impl(.....) { ..... }
void beta()
{
run_and_catch( boost::bind(beta_impl, .....) );
}
// или на макросах ( узнаёте старый злобрый MFC? )
#define BEGIN_RUN_AND_CATCH() try {
#define END_RUN_AND_CATCH() } CATCH_FOO() CATCH_BAR() CATCH_OTHERWISE()
#define CATCH_FOO() catch(Foo const& e) { ..... }
// и т.д.
void alfa(.....)
{
BEGIN_RUN_AND_CATCH()
.....
END_RUN_AND_CATCH()
}
void beta(.....)
{
BEGIN_RUN_AND_CATCH()
.....
END_RUN_AND_CATCH()
}