在回答有关std::stack::pop()
I claimed的问题时pop
未返回该值的原因是出于异常安全原因(如果复制构造函数抛出会发生什么)。
@Konrad评论说,现在有了移动语义,这已经不再适用了。这是真的吗?
AFAIK,移动构造函数can throw
,但也许只有noexcept
它仍然可以实现。
对于奖励积分,此操作提供的线程安全保证是什么?
答案 0 :(得分:3)
当然,并非每个类型都支持移动,C ++ 0x甚至允许抛出移动构造函数。只要从rvalue构造对象可能会抛出它不能是异常安全的。但是,移动语义允许您在给定rvalue源的情况下拥有许多不可构造的类型。
有条件的支持可以通过SFINAE完成。但即使没有这样的条件成员函数,也没有什么能阻止你写作:
auto stack = ...;
auto elem = std::move_if_noexcept(stack.back());
stack.pop_back();
即使你的移动构造函数没有给出强有力的保证,这也是强大的异常保证。
答案 1 :(得分:2)
至于奖金问题,那将不提供线程安全性。考虑一下,作为一个例子,std::vector
的大多数实现都有三个数据元素(指向内存开头的指针,指针1超出已使用数据的末尾,指针1超出已分配内存的末尾)。移动语义允许您移动向量的内容,而无需重新分配和复制值,但这与线程安全无关。你必须使用线程安全的结构来使结构线程安全(因为移动并不意味着 atomic )