В чем смысл std::make_optional

Все std::make_делаются избыточными в C++17 с введением вывода аргументов шаблона класса (кромеmake_unique а также make_shared).

Так в чем смысл std::make_optional? Насколько я могу судить, он делает то же самое, что и руководство по дедукции дляstd::optional.

Есть ли сценарий, когда std::make_optional предпочтительнее руководств по дедукции?

2 ответа

Решение

Один из примеров различий - когда вы хотите (по какой-либо причине) сделать необязательный параметр, содержащий необязательный:

#include <optional>
#include <type_traits>

int main()
{
    auto inner=std::make_optional(325);
    auto opt2=std::make_optional(inner); // makes std::optional<std::optional<int>>
    auto opt3=std::optional(inner);      // just a copy of inner
    static_assert(std::is_same_v<decltype(opt2), std::optional<std::optional<int>>>);
    static_assert(std::is_same_v<decltype(opt3), std::optional<int>>);
}

Другим примером использования for может быть создание объекта, хранящегося в a, без создания для него временного объекта, когда его конструктор принимает несколько аргументов.

Например, рассмотрим следующий класс, конструктор которого имеет несколько аргументов:

      struct Point3D {
   Point3D(int xx, int yy, int zz): x(xx), y(yy), z(zz) {}
   int x, y, z;
};

Представьте, что вы хотите инициализировать объект, хранящийся в Point3D(1, 2, 3)X , тогда вы можете действовать следующим образом:

      std::optional oPoint = Point3D(1, 2, 3);

Однако это создаст временный объект, который затем будет перемещен в папку . Вместо этого, используя шаблон функции удобства, вы можете избежать создания этого временного объекта:

      auto oPoint = std::make_optional<Point3D>(1, 2, 3);

Поскольку мы говорим здесь о C++17 (т.е. std::optionalбыл введен в C++17), здесь применяется гарантированное удаление копии , и поэтому временный объект не создается.


Обратите внимание, что вы все еще можете избежать создания временного объекта без использования, передав std::in_placeк конструктору std::optional<Point3D>объект:

      std::optional<Point3D> oPoint{std::in_place, 1, 2, 3};

Это создаст сохраненный Point3Dобъект на месте , что позволяет избежать создания временного. Тем не менее, вы можете найти это более подробным, чем подход с std::make_optional().


Икс std::optional<Point3D> oPoint(1, 2, 3);не компилируется.

Другие вопросы по тегам