c++ - std::optional 构造函数中 in_place_t 背后的动机
问题描述
我试图更好地理解构造函数背后in_place_t
的动机。std::optional<T>
我得到用例来消除使用默认构造函数构建null
可选与类型的歧义。T
但是,如果为std::optional
构造函数指定了一个或多个参数,那么不能假设它们总是可以转发给构造函数T
吗?
#include <optional>
struct X
{
X(int, int) {}
};
int main()
{
std::optional<X> op{std::in_place, 1,2};
//std::optional<X> op{1,2}; Does not compile, but why can't it be assumed that 1,2 always go to the constructor of X
}
解决方案
它归结为另一个模棱两可。一个例子:如果T
可以从 构造,当从一个对象构造optional<T>
时会发生什么?参数的期望行为是复制构造还是转发给构造函数?optional<T>
optional<T>
optional<T>
T
这在N3527中得到了解决(我从一个相关问题的答案中获得了它的链接。)考虑了转发参数的可能性,但被驳回了。
但是,这种【完美转发】模型也存在一定的问题。首先,完美转发也有例外:标签
nullopt
不转发。此外,类型参数optional<T>
不是。如果 T 有这样的构造函数,这变得可见:struct MyType { MyType(optional<MyType>, int = 0); // ... };
此外,一般情况下,由于涉及特殊的推导规则,不可能完美转发 initializer_list。
该论文还发现了完美转发下的默认构造问题。(默认构造optional<T>
将包含一个 default-constructed而不是不包含值。)这部分可以通过要求标签构造一个包含 default-constructedT
的标签来回避——以一定的一致性为代价。我认为这是较小的障碍,而歧义问题是主要的障碍。in_place_t
optional<T>
T
我想你可以继续问为什么不转发两个或更多参数(当第一个不是标签时)?在某些时候,一致性确实成为了一个理想的目标。保持界面简洁。如果将零个或一个参数转发给 的构造函数需要一个标签T
,那么对于任意数量的参数都需要它。要记住的规则越少,编程错误就越少。
推荐阅读
- assembly - 将汇编文件转换为 nasm 中的十六进制转储
- html - 链接到另一个页面中的部分
- sql - 优化查找好友的查询
- python - 我正在尝试用 Python 编写加密。我的问题是密钥比消息短。因此我应该从钥匙重新开始
- firebase - 无法使用 cypress 使用 Firestore 本地模拟器测试应用程序
- r - 如何在包中设置选项
- python - 如何在python中应用控制点网格来变形图像
- php - 如何在magento2中阻止礼品卡页面的货币切换器
- node.js - 用于自动完成的 VS 代码 npm 扩展对我不起作用
- c# - 使用 TestServer 进行 ASP.net 核心集成测试有什么优势?