在具有标准容器成员的类上实现移动操作的惯用方式不能noexcept
也因此不能通过诸如vector.push_back()
. 还是我弄错了?
从
vector<Elem> data;
// ...
data.push_back( elem );
我们鼓励进行移动操作noexcept
——因此在向量调整大小期间,库可以安全地将元素移动到重新分配的存储中。
class Elem {
// ...
Elem(Elem&&) noexcept; // noexcept important for move
Elem& operator=(Elem&&) noexcept; // noexcept important for move
};
到目前为止一切顺利,现在我elem
的 s 可以更快地推回。
但是:如果我添加一个容器作为成员,我的班级仍然可以标记为 noexcept-move 吗?所有标准容器都没有它们的动作noexcept
!
class Stuff {
vector<int> bulk;
// ...
Stuff(Stuff&& o) // !!! no noexcept because of vector-move
: bulk(move(o.bulk))
{}
Stuff& operator=(Stuff&&) // !!! no noexcept...
{ /* appropriate implementation */ }
};
这也意味着,我们也不能依赖编译器生成的移动操作,对吧?下面的完整类也不会有noexcept
-move-operations,因此不是“快”的,对吗?
struct Holder {
vector<int> bulk;
};
也许vector<int>
移动起来有点太简单了,但是呢vector<Elem>
?
这将对所有以容器为成员的数据结构产生重大影响。