optional<T&>
был удален из стандартизации C++, потому что его использование сомнительно: он ведет себя почти идентично не владеющему T*
с немного другой (и до путаницы отличной от optional<T>
и T*
) семантикой.
optional<T&>
в основном не владеющий T*
красиво и несколько странно завернутый.
Теперь optional<T>
другой зверь.
Я использовал optional<Iterator>
в своих алгоритмах поиска на основе контейнеров. Вместо того, чтобы возвращать end()
, я возвращаю пустой необязательный параметр. Это позволяет пользователям определить без сравнения, не удалось ли им найти элемент, и позволяет использовать код, подобный следующему:
if(linear_search_for( vec, item))
работать, в то время как тот же алгоритм также позволяет вам получить как элемент , так и местоположение элемента в контейнере, если он вам действительно нужен.
Указатели на элементы не дают вам информации о местоположении, которая может вам понадобиться, за исключением смежных контейнеров.
Итак, здесь я создал итератор, допускающий значение NULL, который имеет преимущества итераторов (как правило, работающих с контейнерами разных типов) и указателей (можно проверить на нулевое состояние).
Следующее использование фактически возвращает значение. Предположим, у вас есть функция, которая вычисляет прямоугольник.
Rect GetRect();
теперь это здорово. Но что, если вопрос может быть бессмысленным? Что ж, один из подходов состоит в том, чтобы вернуть пустой прямоугольник или другое значение «флаг».
Необязательный позволяет вам сообщить, что он может вернуть прямоугольник или ничего, и не использовать пустой прямоугольник для состояния «ничего». Это делает возвращаемое значение обнуляемым.
int GetValue();
является лучшим примером. Недопустимое значение может использовать состояние флага int, скажем, -1
, но это заставляет каждого пользователя вашей функции искать и отслеживать состояние флага, а не случайно рассматривать его как нормальное состояние.
Вместо этого optional<int> GetValue()
ясно дает понять, что может произойти сбой, и что означает сбой. Если он заполнен, вы знаете, что это реальное значение, а не значение флага.
В обоих этих случаях возврат указателя, не являющегося владельцем, нецелесообразен, потому что кому принадлежит хранилище? Возврат указателя-владельца обходится дорого, потому что бессмысленное выделение кучи бессмысленно.
Необязательные типы — это типы значений, допускающие значение NULL. Когда вы хотите управлять ресурсами локально, и вам все еще нужно пустое состояние, они ясно дают понять.
Еще одна вещь, на которую стоит обратить внимание, это предлагаемый тип expected
. Это необязательно, но в пустом состоянии содержит причину, почему он пуст.
person
Yakk - Adam Nevraumont
schedule
09.02.2016
find
возвращает тип значения, например.int
илиdouble
? - person CompuChip   schedule 09.02.2016double
по значению (или, лучше,int
по значению), и вы хотите указать, что не нашли ее, вы вернете... что? - person Angew is no longer proud of SO   schedule 09.02.2016optional
по крайней мере проясняет ситуацию для пользователя API. - person Biffen   schedule 09.02.2016findStudent()
новый объект? Полагаю, что нет, но API этого не передает. - person Biffen   schedule 09.02.2016optional
решает эту проблему либо путем копирования результата по значению вызывающей стороне (или, возможно, перемещения его в С++ 11). Право собственности теперь принадлежит вызывающей стороне в форме временного объекта, который затем уничтожается таким образом, который имеет четкую семантику. - person marko   schedule 09.02.2016optional
не столько в техническом плане, сколько в том, чтобы разработчикам было понятнее, что это тип, который может иметь или не иметь стоимость. У указателей много недостатков. Я не буду перечислять их здесь, ноoptional
по крайней мере имеет RAII, которого нет (необработанных) указателей. Возможно, вы представляете идеальный вариант использования указателей, но, по мнению некоторых людей, уoptional
есть и другие. - person Biffen   schedule 09.02.2016