Hi,
>>>> Nil A wrote:
EM>> Вот я тридцать лет писал на C/C++ с возвратом ошибок, и очень не
EM>> хотел использовать исключений (главным образом потому, что ядре
EM>> NT они не поддерживаются, да и не нужны они там).
NA> Есключения в C++ - единственный способ сообщить об ошибке в
NA> конструкторе.
Это как раз нет, потому что всегда есть варианты типа
Buka buka(1,2,3);
if (!buka.isValid()) { отреагировать; }
И это, обратите внимание, в стандартной библиотеке - например, открыв
[i][o]fstream с конкретным именем файла, можно через good() проверить
отсутствие ошибки открытия. (iostream библиотека была стандартизована до
устаканивания исключений.)
А вот то, что с исключениями значительно легче писать
a = b+c*d;
вместо росписи каждой операции с проверкой на ошибку и без особого состояния
каждого объекта, типа знаменитого NaN, - это таки реально важно.
NA> Понятно, что если ты C++ со стажем, ещё с древних C-времём идёшь, то
NA> будут отдельные функции load(), parse(), и все они будут возвращать
NA> код ошибки. Hо если ты пописал немного уже на чём-то
NA> модном-молодёжном, например, том же питоне, то уже и сам начинаешь
NA> думать, а что если прям в конструкторе всё вызывать и кинуть
NA> исключение, если что-то пошло не так.
load(), parse() могут и исключения давать, но если нужно устанавливать какие-то
параметры перед их работой, то это становится единственным нормальным методом.
Это вроде GoF'овского паттерна Builder, только его "внутренний" эквивалент.
NA> Ещё мой наблюдения. Современные учебники по C++17 учат молодёжь
NA> возвращать значения в виде std::optional, типа ты получаешь результат,
NA> или что-то пошло не так, и получается "пусто". Hо как сообщить, что
NA> именно не так пошло? Вот тогда учебники говорят использовать
NA> std::variant - будет тебе либо значение, либо класс ошибки. И, якобы,
NA> std::variant возвращать более кашерно, чем std::tuple (или std::pair)
NA> в формате (result, err). Это, собственно, чем и занимается Golang всю
NA> дорогу.
А я таки думаю, что случай, когда есть одновременно и ошибка, и частичный
результат - это совершенно нормальный случай и его надо тоже поддерживать даже
активнее, чем variant типа "результат или ошибка".
Hапример, мы читаем файл. Попросили 1000 байт, получили только 500. Если
укороченный ответ был вызван не EOF, а ошибкой чтения типа битого блока, ошибка
будет каким-то образом "отложена" в системном состоянии открытого дескриптора и
будет возвращена следующим read(). Hо это, вообще-то, плохой подход
("антипаттерн", как сейчас модно говорить).
Или уже упоминавшееся в этой дискуссии целочисленное переполнение: в GCC ввели
гениальные расширения типа __builtin_add_overflow(), которые выдают _и_ флаг
переполнения, _и_ усечённое значение. Иногда нужен флаг переполнения, иногда -
усечённое значение, а иногда - таки оба, и я могу выбирать, что нужно (а
компилятор, соответственно, выкидывать неиспользованное).
-netch-
... Спамы, куки...