无论我在网上读什么书,都强烈建议如果我希望我的班级与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构造函数
发布评论