Грокаем C++
9.36K subscribers
44 photos
1 video
3 files
562 links
Два сеньора C++ - Владимир и Денис - отныне ваши гиды в этом дремучем мире плюсов.

По всем вопросам (+ реклама) @ninjatelegramm

Менеджер: @Spiral_Yuri
Реклама: https://telega.in/c/grokaemcpp
Мы на TGstat: https://tgstat.ru/channel/@grokaemcpp/stat
Download Telegram
​​Bad practice. Возврат ошибки. Кастомная структура
#новичкам

Если нам запрещают кидать исключения, то надо как-то сообщать об ошибке. И самый прямолинейный способ это сделать - вернуть ошибку в качестве возвращаемого значения. Но как это сделать, если функция при успешном выполнении должна возвращать нормальное значение?

Обернем это все в класс и сделаем его типом возвращаемого значения!

template<typename T>
struct Result {
T value;
std::string error;

static Result ok(T val) {
return Result{std::move(val), {}};
}

static Result fail(std::string err_msg) {
return Result{T{}, std::move(err_msg)};
}

operator bool() const { return error.empty(); }
};

Result<double> safe_divide(double a, double b) {
if (b == 0.0) {
return Result<double>::fail("Division by zero");
}
return Result<double>::ok(a / b);
}

auto div_result = safe_divide(10.0, 2.0);
if (div_result) {
std::cout << "Result: " << div_result.value << std::endl;
} else {
std::cout << "Error: " << div_result.error << std::endl;
}


Без шаблонной магии это выглядит примерно так. 2 условных поля - валидный результат и сообщение об ошибке(код ошибки). Ну и немного полезных методов для красивой инициализации результата.

Этот подход работает, но у него есть несколько весомых недостатков:

🔞 В структуре хранится всегда 2 поля, хотя семантически должно хранится что-то одно. Возвращается либо ошибка, либо валидный результат. Нет суперпозиции. А в коде выше есть. Как минимум это увеличивает размер объекта, а как максимум(при ошибочной реализации и/или использовании, но все же) приводит к той самой суперпозиции, когда есть и ошибка и результат.

🔞 Так как всегда конструируются и результат, и ошибка, то ничто не мешает использовать результат без проверки, вернула ли функция ошибку.

В общем, классы результатов, где 2 поля, но только одно из них всегда актуальное - не очень, так делать не нужно. Такая практика ведет к ошибкам и синтаксически и семантически никак не защищает пользователя от неправильного использования. Есть варианты получше.

You can do better. Stay cool.

#badpractice
👍2210🔥6