Лучшая альтернатива std:: optional для возврата необязательного значения из метода? (с использованием С++ 98/С++ 11/С++ 14)
Очевидно, что std::optional
- лучший выбор для возврата необязательного значения из функции, если использовать С++ 17 или boost (см. также GOTW # 90)
std::optional<double> possiblyFailingCalculation()
Но что и почему будет лучшей альтернативой, если вы застряли с более старой версией (и не можете использовать boost)?
Я вижу несколько вариантов:
-
умные указатели STL (только для С++ 11)
std::unique_ptr<double> possiblyFailingCalculation();
- (+) практически такое же использование, как опция
- (& minus;) сбивает с толку интеллектуальные указатели на неполиморфные типы или встроенные типы
-
Сопряжение с помощью bool
std::pair<double,bool> possiblyFailingCalculation();
-
Старый стиль
bool possiblyFailingCalculation(double& output);
- (& минус;), несовместимый с новым стилем С++ 11
auto value = calculation()
-
Шаблон DIY: базовый шаблон с одинаковой функциональностью достаточно прост для кодирования, но есть ли какие-либо проблемы для реализации надежного шаблона типа std::optional<T>
?
-
Выбросить исключение
- (& minus;) Иногда "невозможно вычислить" является допустимым возвращаемым значением.
Ответы
Ответ 1
std::optional
, как и его родительский boost::optional
, является довольно простым шаблоном класса. Это a bool
, некоторое хранилище и множество функций-членов удобства, большинство из которых являются одной строкой кода и утверждают.
Выбор DIY определенно предпочтительнее. (1) включает в себя выделение и (2), (3) включает в себя необходимость создания T
, даже если вы хотите получить нулевое значение, которое вообще не имеет значения для double
, но имеет значение для более дорогих типов. С (5) исключения не заменяют optional
.
Вы всегда можете сравнить свою реализацию с Boost. В конце концов, это небольшая библиотека только для заголовков.
Ответ 2
Вернуть структуру (или класс, если вы хотите использовать переносные операторы трансляции)