编译但失败的C++std::vector<std::auto_ptr<T>>示例

什么是一个简单的 C++ 程序,其中 astd::vector<std::auto_ptr<T>>编译但无法正确执行,而同一程序std::vector<std::unique_ptr<T>>编译并正常工作,对于某些数据类型T

我知道这std::auto_ptr已被弃用或删除;我只是想,涉及集装箱激励一个例子,为什么它被废弃或删除。

g++-10 -std=c++20在 MacOS Big Sur 版本 11.2.1 上使用。

回答

std::auto_ptr根本不能在标准容器中使用。在这种情况下,它不会保持正确的语义。这就是移动语义std::unique_ptr最初是在 C++11 中发明的原因之一。 std::auto_ptr在 C++11 中被弃用,并在 C++17 中完全删除。所以不要在现代编码中使用它。

官方std::auto_ptr弃用原因如下:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html#20.4.5%20-%20Class%20template%20auto_ptr

给出的示例std::sort()在 a 上使用std::vector<std::auto_ptr<int>>

通过这样的设计,可以将 auto_ptr 放入容器中:

vector<auto_ptr<int> > vec;

然而,这种设计的现场经验揭示了一些微妙的问题。即:

sort(vec.begin(), vec.end(), indirect_less());

根据 的实现sort,上面这行看起来合理的代码可能会也可能不会按预期执行,甚至可能会崩溃!问题是一些实现sort会从序列中挑选一个元素,并存储它的本地副本

...
value_type pivot_element = *mid_point;
...

该算法假设在这种构造之后pivot_element*mid_point是等价的。然而,当value_type结果是 时auto_ptr,这个假设失败了,随后算法也失败了。

解决此问题的方法是auto_ptr通过禁止从const auto_ptr. 使用这样的auto_ptr,如果您尝试将其放入容器中,则会出现编译时错误。

最后的结论是这样的:

调用任何通用代码,无论是否对其std进行操作auto_ptr都是有风险的,因为通用代码可能假设看起来像复制操作的东西实际上复制操作。

结论:

不应使用复制语法从左值移动。应改用其他移动语法。否则,通用代码可能会在需要复制时启动移动。

auto_ptr 使用复制语法从左值移动,因此从根本上是不安全的。

  • The question is specifically asking for an example in which using of `std::auto_ptr` compiles but fails to execute correctly. It remains to be seen whether that's an appropriate question for SO or not. 🙂

以上是编译但失败的C++std::vector&lt;std::auto_ptr&lt;T&gt;&gt;示例的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>