我的最初想法一直是尝试尽可能使用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};
我都不满意。您将如何处理这个问题?
答案 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
情况下,tt
是std::tuple<std::tuple<int>>
。