为什么std :: vector尽管声明为noexcept(false),但仍使用move构造函数 [英] Why does std::vector use the move constructor although declared as noexcept(false)
问题描述
无论我在网上读什么书,都强烈建议如果我希望我的班级与std::vector
一起正常工作(即,我班级的移动语义被std::vector
使用),我应该将care构造函数的delcare移动为'noexcept '(或noexcept(true)
).
Wherever I read in the internet, it is strongly adviced that if I want my class to be working well with std::vector
(i.e. move semantics from my class were used by std::vector
) I should delcare move constructor as 'noexcept' ( or noexcept(true)
).
#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());
}
输出:
T()
T(T&&)
~T()
~T()
为什么? 我做错了什么?
Why ? What did I do wrong ?
在gcc 4.8.2上编译,并将CXX_FLAGS设置为:
Compiled on gcc 4.8.2 with CXX_FLAGS set to:
--std=c++11 -O0 -fno-elide-constructors
推荐答案
您没有做错任何事情.
您只是错误地认为push_back
必须避免抛出move-ctor:至少在构造新元素时不需要这样做.
You just wrongly thought push_back
had to avoid a throwing move-ctor: It does not, at least for constructing the new element.
必须避免唯一的抛出动圈/移动分配的地方是重新分配向量,以避免移动一半的元素,而其余的保留在其原始位置.
The only place where throwing move-ctors / move-assignments must be shunned is on re-allocation of the vector, to avoid having half the elements moved, and the rest in their original places.
该功能具有强大的异常安全保证:
The function has the strong exception-safety guarantee:
要么操作成功,要么操作失败,但没有任何改变.
Either the operation succeeds, or it fails and nothing has changed.
这篇关于为什么std :: vector尽管声明为noexcept(false),但仍使用move构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!