c++ 什么时候使用is_nothrow_constructible?

42fyovps  于 2023-04-01  发布在  其他
关注(0)|答案(2)|浏览(184)

在什么情况下使用is_nothrow_constructible变得很重要?为什么它很重要?它的用途是什么?

j1dl9f46

j1dl9f461#

假设你正在实现new,如果构造函数不能抛出,那么你可以简单地分配内存并执行placement new。
现在如果构造函数可以抛出,你必须添加一个保护,以释放分配的内存,以防异常发生在构造函数中。
如果它是一个new[],它分配了一个某种类型的数组,那么如果数组的元素可以在构造时抛出,那么你应该确保守卫知道到底有多少元素被构造,并在异常时销毁它们,除了释放内存。
好吧,通常不需要实现new,但是定制的vector类或其他一些你想要的容器,手动分配内存并在各种操作中使用placement new呢?
在这种情况下,你可以使用trait来优化构造函数不抛出的情况。

wz3gfoph

wz3gfoph2#

您将看到它的主要用途是计算不同的函数是否应该是noexcept
例如,std::pair的构造函数可能如下所示:

template<typename T1, typename T2>
template<typename T, typename U>
pair<T1, T2>::pair(T&& x, U&& y)
  noexcept(std::is_nothrow_constructible_v<T1, T&&> && std::is_nothrow_constructible_v<T2, U&&>)
   : first(std::forward<T>(x)), second(std::forward<U>(y)) {}

这意味着noexcept-ness可以更好地传播出去,有助于其他一些优化。
std::move_if_noexcept是一种完全不同的行为,它使用std::is_nothrow_constructible<T, T&&>来决定是否应该从其中移动或复制某些内容。
它用于维护“强异常保证”。例如,当调整向量大小时,如果它不能抛出,它将把项移动到新的内存中,否则它将复制(如果复制抛出,原始内容仍然有效)。

相关问题