std::pair的潜在危险隐式转换是故意的吗?有办法避开他们吗



我刚刚意识到这段代码编译得很好,但有未定义的行为,并且(自然(在运行时崩溃:

#include <map>
#include <memory>
#include <utility>
int main(int argc, char *argv[])
{
std::pair<std::unique_ptr<int>, int> a(&argc, 0);
std::map<std::unique_ptr<int>, int> m; m.insert(std::make_pair(&argc, argc));
}

这对我来说有点震惊,因为我只是自然地认为std::unique_ptr<T>T*构造函数的explicit特性会阻止我意外地将T *转换为std::unique_ptr<T>,但在一些转发给构造函数的包装器(如std::pair(中,这种保护似乎不再起作用。

所以我想我想知道一些事情:

  • 对此有很好的缓解措施吗?这是一个众所周知的问题吗?

  • 这些是故意的,还是应该被视为标准中的缺陷?

  • 如果这是一个缺陷,应该做什么纠正?它可以在库级别制作,还是需要更改语言?(例如,它是否需要explicit的过载能力?(

请记住,std::unique_ptr<int>只是一个例子;代码错误并不总是显而易见的,而且代码模板化得越多,预测潜在危险的转换就变得越来越困难,所以我真的很想知道人们是如何处理的。

您正在调用std::pair<std::unique_ptr<int>, int>的显式构造函数,它继承了std::unique_ptr<int>的构造函数的显式性。

std::unique_ptr<int> p(&argc);基本相同。你必须对此保持警惕。

容器拥有它们的元素,insertemplace必须构造值。insertemplace不是构造函数或转换运算符,不能标记为explicit

必须在";并非偶然";以及";迟钝的故意做";。拥有转发构造函数(从C++20中有条件地显式(是委员会做出的选择。

Containers的emplace方法就是最显著的例子;是的,这是意向性的。

相关内容

最新更新