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