Итак, я столкнулся с этим (IMHO) очень хорошей идеей использования составной структуры возвращаемого значения и исключения - Expected<T>
. Он преодолевает многие недостатки традиционных методов обработки ошибок (исключения, коды ошибок).
См. Обсуждение Андрея Александреску (систематическая обработка ошибок на С++) и его слайды.
Исключения и коды ошибок имеют в основном одинаковые сценарии использования с функциями, которые возвращают что-то, а те, которые этого не делают. Expected<T>
, с другой стороны, похоже, нацелен только на функции, возвращающие значения.
Итак, мои вопросы:
- Кто-нибудь из вас пробовал
Expected<T>
на практике? - Как вы примените эту идиому к функциям, возвращающим ничего (т.е. функции void)?
Update:
Думаю, я должен уточнить свой вопрос. Специализация Expected<void>
имеет смысл, но меня больше интересует, как она будет использоваться - последовательная идиома использования. Сама реализация является вторичной (и простой).
Например, Alexandrescu дает этот пример (немного отредактированный):
string s = readline();
auto x = parseInt(s).get(); // throw on error
auto y = parseInt(s); // won’t throw
if (!y.valid()) {
// ...
}
Этот код "чистый" таким образом, что он просто протекает естественным образом. Нам нужна ценность - мы ее получаем. Однако при Expected<void>
нужно было бы захватить возвращаемую переменную и выполнить некоторую операцию над ней (например, .throwIfError()
или что-то еще), что не так элегантно. И, очевидно, .get()
не имеет смысла с void.
Итак, как бы выглядел ваш код, если бы у вас была другая функция, скажем toUpper(s)
, которая изменяет строку на месте и не имеет возвращаемого значения?