В Оберон (точнее в один из его диалектов), где, как известно нет исключений и подобных механизмов, предлагается ввести новую синтаксическую конструкцию :
Первый_этап;
IF первый этап удался THEN
Второй_этап
AND второй этап удался THEN
Третий_этап
AND третий этап удался THEN
Завершающие действия
ELSE
Задача не выполнена
END
Соотвественно если нам нужно определить на каком этапе случилась ошибка, то пишется это так:step := 1;
Первый_этап;
IF первый этап удался THEN
step := 2;
Второй этап;
AND второй этап удался THEN
...
ELSE
Log.String("Ошибка на этапе "); Log.Int(step)
END
Но это конечно трубует менять язык. Соответственно менять компилятор. Что не здорово, лень и вообще не факт что кто-то будет делать.Однако в С++ мы иногда тоже не можем пользоваться исключениями. Ну, например если мы от них намерянно отказались (см. например Google C++ Style). Менять компилятор С++ тоже совсем не интересно, но это и не нужно. Всё вышеперечисленное легко реализуется средствами самого языка, при чем без шаблонов и прочего метапрограммирования.
Нам достаточно того, что в С++ есть оператор запятая (,) и есть ленивые вычисления. Соответственно концепт такой:
bool r = (
A1, // первый этап
A2,
A3,
первый_этап_удался ) and (
B1, // второй этап
B2,
B3,
второй_этап_удался ) and (
C1, // третий этап
C2,
C3,
третий_этап_удался ) and (
Z1, // завершаюшие действия
Z2,
Z3,
true ) or (
ERR1, // Задача не выполнена
ERR2,
ERR3,
false);
Ну и, как обычно, рабочий пример:Соответственно результат запуска такой:#include <iostream> bool zoo(int c) { int z = c; int step = 1; bool r = ( step = 1, z--, std::cout << "step 1: " << z << std::endl, z > 0 ) and ( step = 2, z-- , std::cout << "step 2: " << z << std::endl, z > 0 ) and ( step = 3, z--, std::cout << "step 3: " << z << std::endl, z > 0 ) and ( z = z*z, std::cout << "Ending... " << z << std::endl, true ) or ( std::cout << "Error on step " << step << std::endl, false ); return r; } int main() { zoo(4); zoo(3); zoo(2); zoo(1); zoo(0); }
step 1: 3 step 2: 2 step 3: 1 Ending... 1 step 1: 2 step 2: 1 step 3: 0 Error on step 3 step 1: 1 step 2: 0 Error on step 2 step 1: 0 Error on step 1 step 1: -1 Error on step 1
