【发布时间】:2019-09-16 21:15:34
【问题描述】:
显然,std::move_if_noexcept() 将调用移动构造函数,即使它没有标记为 noexcept,如果没有可用的复制构造函数。
来自cpprefeerence.com(强调我的):
注意事项
例如,
std::vector::resize使用它,它可能必须分配新存储空间,然后将元素从旧存储空间移动或复制到新存储空间。如果在此操作过程中发生异常,std::vector::resize会撤消它到此为止所做的一切,这只有在使用std::move_if_noexcept来决定是使用移动构造还是复制构造时才有可能。 (除非复制构造函数不可用,在这种情况下,无论哪种方式都使用移动构造函数,并且可以放弃强异常保证)
由于std::vector 在重新分配时使用此函数,这可能会使向量和可能的应用程序处于未确定状态。那么,为什么会允许这样做呢?
【问题讨论】:
-
您想从设计会议的会议中获得报价,或者这对软件有什么好处?其次,IIRC,这些规则随着时间的推移发生了变化。您想要回答哪个 C++ 的确切版本? C++11?我要求您尽可能缩小您的问题范围。
-
@Yakk-AdamNevraumont,好处,尽管引用可能有助于理解它们。如果规则随着时间而改变,那么了解它的演变到当前状态也可能很有用。仅在引入时将其标记为 c++11。
-
您是否有另一种行为?是否根本不可能将
vector用于此类类型,即使没有强有力的保证,它是否有用? -
@DavisHerring,如果你没有这样的保证,那会发生什么?新位置及其所有已移动的元素都被销毁,旧位置中的一些元素处于有效但未确定的状态。所以我想不会发生资源泄漏,可以吗?任何可能引用向量的东西都必须考虑到这一点,我想这是可行的。如果抛出的异常被包装在另一个中以说明什么范围无效,则可能很有用。
-
@Adrian:您得到了基本保证——
vector处于有效但未指定的状态,没有泄漏,您可能能够分辨出哪个元素未能从异常中移动。