Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Вопрос — планируется ли в плюсах поддержка "фильтров исключений"?
Есть фильтр по типу исключений. В if(!<некоторое условие>) throw; можно поменять тип. На мой взгляд этого достаточно, а про то, что планируется я не в курсе.
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Вопрос — планируется ли в плюсах поддержка "фильтров исключений"?
КД>Ну, то есть, привязка к catch дополнительного вычисляемого условия.
В Structured Exception Handling всегда можно было (хотя это не плюсы, конечно же):
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Привет всем.
КД>Засунув в десяток catch-ей
ну если эти catch'и одной кучей подряд идут, то:
try
{
// сильно много исключений вылетает отсюда
}
catch(...)
{
if (!<некоторое условие>)
throw;
// ок, посмотрим что же там произошло и решим что делать...try
{
throw;
}
catch (const database::exception& e)
{
//
}
catch (const http::exception& e)
{
//
}
catch (const std::runtime_exception& e)
{
//
}
catch (const std::exception& e)
{
//
}
}
если нет... т.е. ты порефачил реальную кучу файлов/функций с одиночными catch блоками... то запись
catch (const std::exeception& e) if (some_condition)
{
}
или как бы там этот синтаксический сахар не выглядел... не особо лучше/короче приведенного тобой кода -- так или иначе `some_condition` нужно написать,
а в твоем коде, IMHO, синтаксического шума не сказать что много, чтобы запариваться на "фильтры исключений" и прочий сахар, да еще и добавляя что-то в язык!
КД>Задумался — а зачем вообще заходит в catch?
"заходить" в catch в целом то, не страшно, когда у тебя таблицы... с сахаром или без, тип исключения тоже нужно будет проверять по любому... и не факт что эта проверка "дороже" чем вычисление "некоторого условия" %)
КД>Вопрос — планируется ли в плюсах поддержка "фильтров исключений"?
если ты не напишешь офигительный proposal в комитет, IMHO наврядли кто-то будет рассматривать подобное улучшение в языке %)
КД>Просьба не предлагать организовывать две ветки кода.
это как?
ЗЫ кстати весь код ниже коммента "// ок, ..." можно вынести в отдельную функцию и реюзать, если подобных блоков catch много где встречается...
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Вопрос — планируется ли в плюсах поддержка "фильтров исключений"?
Дык по типу исключения всё фильтруется на ура. Просто ловишь исключение конкретного типа и обрабатываешь. КД>Ну, то есть, привязка к catch дополнительного вычисляемого условия. КД>Типа catch_if какой-нибудь?
Зачем? У тебя есть желание построить логику работы программы на исключениях? Это неправильно.
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Вопрос — планируется ли в плюсах поддержка "фильтров исключений"? КД>Ну, то есть, привязка к catch дополнительного вычисляемого условия. КД>Типа catch_if какой-нибудь?
Тут надо заметить, что гребёнка catch(Type){if(!test)throw;...} не эквивалентна гребёнке catch_if(Type,test){...}
try { // какой-то внешний блокtry { foo(); }
catch(A a) { if(!test_a()) throw; accept_a(); } // по else прыгнем сразу на catch(D) и далееcatch(B b) { if(!test_b()) throw; accept_b(); } // по else прыгнем сразу на catch(D) и далееcatch(...) { accept_c(); }
}
catch(D d) { accept_d(); }
catch(...) { accept_e(); }
Почти — потому что надо различать, когда мы делаем throw с целью продолжить диспетчеризацию, а когда новое исключение вылетает из недр accept...
А ещё, исключение может вылететь из test...
Наверно, можно как-то выкрутиться с помощью магии препроцессора, шаблонов и лямбд, чтобы синтаксис гребёнки превратить в семантику лестницы.
Что-то в таком роде
Здравствуйте, Кодт, Вы писали: КД>>Вопрос — планируется ли в плюсах поддержка "фильтров исключений"? КД>>Ну, то есть, привязка к catch дополнительного вычисляемого условия. КД>>Типа catch_if какой-нибудь? К>Наверно, можно как-то выкрутиться с помощью магии препроцессора, шаблонов и лямбд, чтобы синтаксис гребёнки превратить в семантику лестницы. К>Что-то в таком роде
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Ох, нет... КД>Магию и компанию — фтопку. КД>Чем проще, тем лучше. КД>Оставил самый первый вариант
Поскольку здесь ровно один catch, то всё, что нужно проверить — это гигиена повторных исключений.
Что если внутри catch-блока что-то вылетит, то вызывающая сторона будет к этому так же готова, как к необработанному исключению из try-блока. (Либо гарантировать, что из catch ничего, кроме "throw;" не вылетит).
А вот что насторожило, — это то, что исключение размазано: половина информации находится собственно в объекте-наследнике std::exception, вторая половина — в каких-то свойствах m_connection.
Почему бы в тех местах, где взводится флажок err_rules__explain_dbms_error(), не кидать исключение соответствующего типа? И затем ловить его.
Ну и не забываем про множественное наследование.
class my_error_base : public std::runtime_error { ..... };
// семейство исключений, по одному признаку на классclass my_dbms_error : public my_error_base { ..... };
class my_dbms_sql_error : public my_dbms_error { ..... };
class my_network_error : public my_error_base { ..... };
// семейство исключений, по сочетанию флаговclass my_flag1_error : public virtual my_error_base {};
class my_flag2_error : public virtual my_error_base {};
class my_flag4_error : public virtual my_error_base {};
class my_flags_1_and_2_error : public my_flag1_error, public my_flag2_error {};
try {
.....
throw my_flags_1_and_2_error(the_connection, other_helpful_stuff);
.....
} catch(const my_flag1_error& e) {
const& my_error_base meb = e; // и извлечём оттуда the_connection и т.п.
.....
}
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Засунув в десяток catch-ей КД>... КД>Задумался — а зачем вообще заходит в catch?
Несколько лет назад здесь проскакивала достаточно элегантная реализация фильтра исключений. Найти ссылку сходу не удалось, но идея была примерно такая:
Здравствуйте, Кодт, Вы писали:
К>А вот что насторожило, — это то, что исключение размазано: половина информации находится собственно в объекте-наследнике std::exception, вторая половина — в каких-то свойствах m_connection.
В наследнике std::exception находится описание ошибки (в нем, вообще говоря, "возится" коллекция ошибок).
А в connection находятся настройки, среди которых есть настройка детализации описания ошибок.
Предвижу вопрос — "почему бы не выкидывать полное описание ошибки, а в точке обработки урезать лишнее?"
Ответ — (1) все не так просто. (2) ни осилил.
К>Почему бы в тех местах, где взводится флажок err_rules__explain_dbms_error(), не кидать исключение соответствующего типа? И затем ловить его.
Оно все ловится на уровне интерфейса COM-объекта, перепаковывается в COM-объект, который потом возвращается клиенту через SetError.
К>Ну и не забываем про множественное наследование.
Это все красиво. Но не более
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, rg45, Вы писали:
КД>>Задумался — а зачем вообще заходит в catch?
R>Несколько лет назад здесь проскакивала достаточно элегантная реализация фильтра исключений. Найти ссылку сходу не удалось, но идея была примерно такая: