为什么std :: vector使用移动构造函数,尽管声明为noexcept(false)

Grz*_*zak 7 c++ vector move-semantics noexcept c++11

无论我在互联网上阅读什么,强烈建议如果我希望我的班级能够很好地使用std::vector(即从我的班级移动语义std::vector),我应该将构造函数移动为"noexcept"(或noexcept(true)).

为什么std::vector使用它,即使我将其标记noexcept(false)为实验?

#include <iostream>
#include <vector>
using std::cout;

struct T
{
    T() { cout <<"T()\n"; }

    T(const T&) { cout <<"T(const T&)\n"; }

    T& operator= (const T&)
    { cout <<"T& operator= (const T&)\n"; return *this; }

    ~T() { cout << "~T()\n"; }

    T& operator=(T&&) noexcept(false)
    { cout <<"T& operator=(T&&)\n"; return *this; }

    T(T&&) noexcept(false)
    { cout << "T(T&&)\n"; }
};

int main()
{
    std::vector<T> t_vec;
    t_vec.push_back(T());
}
Run Code Online (Sandbox Code Playgroud)

输出:

T()
T(T&&)
~T()
~T()
Run Code Online (Sandbox Code Playgroud)

为什么?我做错了什么 ?

在gcc 4.8.2上编译,CXX_FLAGS设置为:

--std=c++11 -O0 -fno-elide-constructors
Run Code Online (Sandbox Code Playgroud)

Ded*_*tor 12

你没有做错任何事.

你只是错误地认为push_back必须避免投掷移动 - 它没有,至少在构建新元素时.

必须避免投掷移动控制器/移动分配的唯一地方是重新分配矢量,以避免移动一半元素,其余元素移动到原始位置.

该功能具有强大的异常安全保证:

操作成功,或者失败并且没有任何改变.