Блоки try-функций представляют собой особую форму тел функций, например:
int f() try {
// function body
}
catch {
// one or more catch-clauses.
}
Основное назначение — использование в конструкторах, чтобы регистрировать исключения, генерируемые конструктором любого базового класса. Однако разрешено использовать их и в обычных функциях.
Есть некоторые (довольно старые) вопросы по этому вопросу, спрашивающие, зачем нам это нужно для обычных функций, например Функция try блоков, но не в конструкторах. Тем не менее, мой вопрос немного больше в другом направлении: могу ли я использовать его в обычных функциях в качестве замены обычного блока try без проблем? Допустим, только по эстетическим соображениям?
Я разрабатываю C-интерфейс для C ++ — библиотеки и должен инкапсулировать каждую интерфейсную функцию с блоком try, чтобы перехватывать любые исключения. Таким образом, я хотел бы избежать дополнительного блока фигурных скобок в каждой функции …
Только одна вещь, которая подняла мои опасения: в ответ https://stackoverflow.com/a/11535436/6695750, Давка цитирует статью 2000 года, утверждая, что вы не можете вернуть значение из блока catch, соответствующего функции-try-block. Я тестировал с gcc 5.4.0, там я могу вернуть значение из catch-блока без проблем. Это стандартное или нестандартное расширение gcc?
int f() try {
// function body
}
catch (/*..*/){
// one or more catch-clauses.
}
эквивалентно
int f() {
try {
// function body
}
catch (/*..*/){
// one or more catch-clauses.
}
}
для обычных функций.
Только конструктор / деструктор имеет специальную обработку, поскольку блоки catch генерируют исключение (неявно или явно).
смотрите также документ здесь.
Могу ли я использовать его в обычных функциях в качестве замены обычного блока try без проблем?
В некоторых случаях вы не можете использовать function-try-block
: Вы не можете получить доступ к любым локальным переменным в catch
пункт.
void g() {
int i = 2;
try {
throw 2.3;
} catch (double d) {
cout << i << endl; // OK. you can access i
cout << d << endl;
}
}
void f() try {
int i = 2;
throw 2.3;
} catch (double d) {
cout << i << endl; // FAIL! i is out of scope, you CANNOT access it.
cout << d << endl;
}