我最初的想法一直是尽可能尝试使用 make-helper 函数(也是因为它们与 almost-always-auto 概念和 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 是在 pair 中默认构造的
auto p = std::pair<Widget, Widget>{};
然后我了解到 std::make_pair 基本上已经被 C++17 类模板参数推导功能和推导指南淘汰了,对吗?如果是这样,如何在不显式指定模板参数的情况下使用采用整数的构造函数初始化这对 Widget?
所以我转向我的代码库中的行并尝试替换出现的 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};
我对这两个都不是特别满意。你会如何处理这个问题?
最佳答案
正如您所注意到的,类模板参数推导并没有使 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>>
.
关于c++ - std::make_pair 和 std::make_optional 之间的一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52755748/