Подтвердить что ты не робот

Лучшая альтернатива 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;) Иногда "невозможно вычислить" является допустимым возвращаемым значением.
4b9b3361

Ответ 1

std::optional, как и его родительский boost::optional, является довольно простым шаблоном класса. Это a bool, некоторое хранилище и множество функций-членов удобства, большинство из которых являются одной строкой кода и утверждают.

Выбор DIY определенно предпочтительнее. (1) включает в себя выделение и (2), (3) включает в себя необходимость создания T, даже если вы хотите получить нулевое значение, которое вообще не имеет значения для double, но имеет значение для более дорогих типов. С (5) исключения не заменяют optional.

Вы всегда можете сравнить свою реализацию с Boost. В конце концов, это небольшая библиотека только для заголовков.

Ответ 2

Вернуть структуру (или класс, если вы хотите использовать переносные операторы трансляции)