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

问题描述 投票:2回答:1

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

#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的构造函数允许在这里使用更简洁的语法,因为这两个Widgets是默认构造的

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

然后我了解到std :: make_pair基本上已经过时使用C ++ 17类模板参数演绎功能和演绎指南,这是正确的吗?如果是这样,如何在没有明确指定模板参数的情况下使用构造函数初始化这对Widgets?

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

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

麻烦开始时进入std :: optional

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

虽然第一个选项在可选项中创建默认构造的Widget,但第二个变量仅创建一个空的可选项。有一种替代方案可以使构造更加冗长:std :: in_place。也总是有使用emplace()的选项,但这使得代码成为双线程。现在我在继续使用std :: make_optional和使用verbose选项之间徘徊

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

我对此都不满意。你会怎么解决这个问题?

c++ optional std-pair construct
1个回答
1
投票

正如您所注意到的,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>>

© www.soinside.com 2019 - 2024. All rights reserved.