考虑以下具有 move 构造函数和 move 赋值运算符的类:
class my_class
{
protected:
double *my_data;
uint64_t my_data_length;
}
my_class(my_class&& other) noexcept : my_data_length{other.my_data_length}, my_data{other.my_data}
{
// Steal the data
other.my_data = nullptr;
other.my_data_length = 0;
}
const my_class& operator=(my_class&& other) noexcept
{
// Steal the data
std::swap(my_data_length, other.my_data_length);
std::swap(my_data, other.my_data);
return *this;
}
noexcept
的目的是什么这里?我知道这是对编译器的打击,即以下函数不应抛出异常 but how does this enable compiler optimizations?
最佳答案
noexcept
的特殊重要性 move 构造函数和赋值运算符在 https://vimeo.com/channels/ndc2014/97337253 中有详细说明。
基本上,它不会启用传统意义上的“优化”,即允许编译器生成更好的代码。相反,它允许其他类型(例如库中的容器)在检测到 move 元素类型永远不会抛出时采用不同的代码路径。这可以启用替代代码路径,如果它们可以抛出则不安全(例如,因为它会阻止容器满足 exception-safety guarantees )。
例如,当您执行 push_back(t)
在向量上,如果向量已满(size() == capacity()
),则需要分配新的内存块并将所有现有元素复制到新内存中。如果复制任何元素引发异常,那么库只会销毁它在新存储中创建的所有元素并释放新内存,保持原始向量不变(从而满足强大的异常安全保证)。将现有元素 move 到新存储会更快,但如果 move 可以抛出,那么任何已经 move 的元素都已经被改变并且不可能满足强保证,因此库只会尝试 move 它们它知道不能扔,它只能知道它们是否是noexcept
.
关于c++11 - C++ 为什么在 move 构造函数和 move 赋值运算符的上下文中需要 noexcept 来启用优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32224352/