我刚刚意识到这段代码编译得很好,但是在运行时有未定义的行为和(自然)崩溃:
#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));
}
这对我来说有点令人震惊,因为我很自然地假设'构造函数的explicit
性质会阻止我意外地将 a 转换为,但似乎这种保护措施不再在一些转发给构造函数的包装器中起作用,例如.std::unique_ptr<T>
T*
T *
std::unique_ptr<T>
std::pair
所以我想我想知道一些事情:
有没有很好的缓解方法?这是一个众所周知的问题吗?
这些是故意的,还是应该被视为标准中的缺陷?
如果是缺陷,应该进行哪些更正?可以在图书馆级别制作,还是需要更改语言?(例如,它是否需要
explicit
-ness 的可重载性?)
记住std::unique_ptr<int>
只是一个例子;代码错误并不总是很明显,而且随着代码的模板化越多,预测潜在危险的转换就会变得越来越困难,所以我真的很想知道人们是如何处理这个问题的。