16

std::make_C++17 引入了Class 模板参数推导(除了make_uniqueand make_shared) ,使所有这些都变得多余。

那么有什么意义std::make_optional呢?据我所知,它std::optional.

是否存在std::make_optional优先于扣除指南的情况?

4

2 回答 2

12

差异的一个示例是当您想要(无论出于何种原因)制作一个包含可选的可选时:

#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>>);
}
于 2020-07-04T22:36:35.963 回答
2

另一个使用 for 的示例是std::make_optional()构造存储在 a 中的对象,std::optional而当它的构造函数接受多个参数时,不为其创建临时对象。

例如,考虑以下Point3D类,其构造函数有多个参数:

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

想象一下,您想将 a 存储的对象初始化std::optional<Point3D>Point3D(1, 2, 3)X,那么您可以这样进行:

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

但是,这会创建一个Point3D临时对象,然后将其移动到std::optional. 相反,通过使用std::make_optional()便捷函数模板,您可以避免创建该临时函数:

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

由于我们在这里讨论的是 C++17(即std::optional在 C++17 中引入),因此这里适用保证复制省略,因此不会Point3D创建临时对象。


请注意,您仍然可以std::make_optional()通过传递std::in_place给对象的构造函数来避免创建临时对象而不使用std::optional<Point3D>

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

这将在原地Point3D构造存储的对象,从而避免创建临时对象。不过,您可能会发现这比使用.std::make_optional()


Xstd::optional<Point3D> oPoint(1, 2, 3);无法编译。

于 2020-12-20T17:15:56.140 回答