std :: make_pair和std :: make_optional之间的一致性

时间:2018-10-11 08:37:50

标签: c++ optional std-pair construct

我的最初想法一直是尝试尽可能使用make-helper函数(也因为它们与几乎总是自动的概念和East-initialization约定完全一致),同时尝试在可以避免的副本和移动数量。例如,考虑一对两个默认可构造的小部件

#include<utility>
#include<iostream>

struct Widget{
  Widget() { std::cout << "Default ctor\n"; }
  explicit Widget(int i) : i_{i} { std::cout << "Custom ctor\n"; }
  int i_;
};

auto p = std::make_pair<Widget,Widget>({},{});

但是这种语法很笨拙,看起来很凌乱,并且std :: pair的构造函数在这里允许使用更简洁的语法,因为两个Widget是在该对内默认构造的

auto p = std::pair<Widget, Widget>{};

然后我了解到,使用C ++ 17类模板参数推论功能和推论指南已使std :: make_pair基本过时,对吗?如果是这样,如何在不显式指定模板参数的情况下使用构造函数将这对Widget初始化为整数?

所以我转到代码库中的行,并尝试替换出现的std :: make_optional

auto o = std::make_optional<Widget>{}

进入std ::麻烦开始时可以选择

auto o = std::optional<Widget>{};

虽然第一个选项在可选项内创建了一个默认构造的Widget,但第二个变量仅创建了一个空的可选项。 还有一种选择可以使构造更加复杂:std :: in_place。也总是有使用emplace()的选项,但这使代码变成了两层。现在,我在继续使用std :: make_optional和使用详细选项之间陷入困境

auto o = std::optional<Widget>{std::in_place};

我都不满意。您将如何处理这个问题?

1 个答案:

答案 0 :(得分:0)

您已经注意到,类模板参数推导不会使make函数过时。

您在这里看到的是make创建的值和默认构造的包装器之间存在差异的事实。

另一个示例是使用make_tuple

auto t = std::make_tuple(42);
auto tt = std::make_tuple(t);

这与

不同
auto t = std::tuple{42};
auto tt = std::tuple{t};

后者将调用t的副本构造函数,从而产生std::tuple<int>,而在make_tuple情况下,ttstd::tuple<std::tuple<int>>