Another example of a use for std::make_optional() would be for constructing the object stored in a std::optional without creating a temporary for it when its constructor takes multiple arguments.
For example, consider the following Point3D class whose constructor has multiple arguments:
struct Point3D {
   Point3D(int xx, int yy, int zz): x(xx), y(yy), z(zz) {}
   int x, y, z;
};
Imagine that you want to initialize the object stored by a std::optional<Point3D> to Point3D(1, 2, 3)X, then you could proceed as:
std::optional oPoint = Point3D(1, 2, 3);
However, this would create a Point3D temporary object that is then moved into the std::optional. Instead, by using the std::make_optional() convenience function template you can avoid the creation of that temporary:
auto oPoint = std::make_optional<Point3D>(1, 2, 3);
Since we are talking about C++17 here (i.e., std::optional was introduced in C++17), guaranteed copy elision applies here, and therefore no Point3D temporary object is created.
Note that you can still avoid the creation of the temporary object without using std::make_optional() by passing std::in_place to the constructor of the std::optional<Point3D> object:
std::optional<Point3D> oPoint{std::in_place, 1, 2, 3};
This will construct the stored Point3D object in place, thus avoiding the creation of a temporary. Nevertheless, you may find this more verbose than the approach with std::make_optional().
Xstd::optional<Point3D> oPoint(1, 2, 3); doesn't compile.