10

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

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

AFAIK,移动构造函数可以 throw,但也许noexcept仍然可以实现。

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

4

2 回答 2

3

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

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

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

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

于 2010-04-12T07:13:39.223 回答
3

至于奖金问题,那将不提供线程安全。例如,考虑到大多数实现std::vector具有三个数据元素(指向内存开头的指针、超出已用数据末尾的指针、超出已分配内存末尾的指针)。移动语义允许您移动向量的内容,而无需重新分配和复制值,但这与线程安全无关。您必须使用线程安全构造来使结构线程安全(因为移动并不意味着以任何方式atomic

于 2010-04-12T07:27:27.230 回答