c++11 - C++ 为什么在 move 构造函数和 move 赋值运算符的上下文中需要 noexcept 来启用优化?

标签 c++11 move-semantics noexcept

考虑以下具有 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/

相关文章:

c++ - 是否可以从 c++ 类模拟私有(private)/ protected 方法而不从它继承?

c++ - 为什么使用 'operator==' 时出现错误 no match for `std::find` ?

c++ - 在 C++11 中抛出异常时是否使用 move 语义?

c++ - 是否有模仿临时变量的 C++ 变量类型?

c++ - No-except 没有传递参数

c++ - 违反 noexcept 保证的编译器警告或静态分析?

c++ - 在 gdb 中调试 map<int, unique_ptr<A>>

c++ - vc++ 2010/2012:包含 unique_ptr 的结构的 std::vector 编译器错误

c++ - 将不可复制的闭包对象传递给 std::function 参数

c++ - 当参数按值传递时抛出异常