堆栈是否可以有一个异常安全的方法来使用移动语义返回和删除顶部元素?

发布于 2024-08-29 05:30:17 字数 702 浏览 9 评论 0原文

在回答有关 std::stack::pop() 的问题 我声称 pop 不返回值的原因是出于异常安全原因(如果复制构造函数抛出异常会发生什么)。

@Konrad 评论说,现在有了移动语义,这不再相关。这是真的吗?

AFAIK,移动构造函数可以 抛出,但也许与 noexcept 还是可以实现的。

对于奖励积分,此操作可以提供哪些线程安全保证?

In an answer to a question about std::stack::pop() I claimed that the reason pop does not return the value is for exception safety reason (what happens if the copy constructor throws).

@Konrad commented that now with move semantics this is no longer relevant. Is this true?

AFAIK, move constructors can throw, but perhaps with noexcept it can still be achieved.

For bonus points what thread safety guarantees can this operation supply?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七颜 2024-09-05 05:30:17

当然,并非每种类型都支持移动,C++0x 甚至允许抛出移动构造函数。只要从右值构造对象可能会抛出异常,它就不可能是异常安全的。然而,移动语义允许您拥有许多在给定右值源的情况下不可抛出构造的类型。

SFINAE 可以对此提供有条件的支持。但即使没有这样的条件成员函数,也没有什么可以阻止您编写:

auto stack = ...;
auto elem = std::move_if_noexcept(stack.back());
stack.pop_back();

即使您的移动构造函数没有提供强有力的保证,这也可以提供强有力的异常保证。

Of course, not every type is move-enabled and C++0x even allows throwing move constructors. As long as constructing the object from an rvalue may throw it cannot be exception-safe. However, move semantics allows you to have many types that are nothrow-constructible given an rvalue source.

Conditional support for this could be done with SFINAE. But even without such a conditional member function nothing stops you from writing:

auto stack = ...;
auto elem = std::move_if_noexcept(stack.back());
stack.pop_back();

which is makes the strong exception guarantee even in case your move constructor doesn't give the strong guarantee.

只是一片海 2024-09-05 05:30:17

至于额外的问题,这不会提供线程安全性。举个例子,std::vector 的大多数实现都具有三个数据元素(指向内存开头的指针、超出已用数据末尾的指针、超出分配内存末尾的指针)。移动语义允许您移动向量的内容,而无需重新分配和复制值,但这与线程安全无关。您必须使用线程安全的构造来使结构线程安全(因为移动并不意味着原子

As for the bonus question, that would offer no thread-safety. Consider that, as an example, most implementations of std::vector have three data elements (pointer to beginning of memory, pointer one beyond end of used data, pointer one beyond end of allocated memory). Move semantics allow you to move the contents of the vector without the need to reallocate and copy values, but that has nothing to do with thread safety. You would have to use thread-safe constructs to make the structure thread safe (as moving does not imply by any means atomic)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文