如果T不可移动,std :: vector <T>是否可移动?

gal*_*tte 5 c++ vector move-semantics c++11

我试图移动一个明显不可移动的std::vector<T>地方时发生了崩溃T(没有定义移动构造函数/赋值运算符,它包含内部指针)

但是为什么vector的移动函数想调用移动函数T?它没有必要.

所以我的问题来自标题:std::vector<T>移动是否T可移动?

dyp*_*dyp 6

n3797的[container.requirements.general]中关于"分配器识别容器要求"的表99说明了移动构造:

要求:移动施工A不得通过例外退出.

A分配器类型在哪里.它不需要MoveInsertable作为值类型.

时间复杂度要求是:"常数",顺便说一句.


std::vector通常存储一些指针加上分配器.移动构造a时std::vector,只需移动指针和分配器.不需要触摸元素.


Moo*_*uck 6

  1. 是的,std::vector<T>即使T不可移动也可移动.左侧仅取得右侧矢量的所有权,不触及任何元素.(有一个例外,列在#2中)

  2. a的移动分配vector只会调用移动构造函数或移动赋值,T如果它们和它们的分配器比较相等而左侧的分配器propagate_on_container_move_assignmentfalse.(请注意,如果您的移动构造函数可能抛出或不存在,则将使用复制构造函数)但是,您不太可能遇到其中任何一个.

    Reworded:如果propagate_on_container_move_assignmenttrue(通常是),那么vector它总是可移动的,并且不会触及单个元素.如果是false,但分配器比较相等,则移动向量而不触及单个元素.如果它是假的并且分配器比较不等,则将转移各个元素.如果存在nothrow移动分配,则使用该分配.否则,如果存在复制构造函数,则使用该复制构造函数.否则使用投掷移动分配.如果它既不可移动也不可复制,那就是未定义的行为.

  3. 没有定义移动赋值运算符,并且包含内部指针的类并不意味着您的类不可移动.事实上,这听起来像编译器认为它可移动的.如果你想禁用移动,请使用T(T&&) = delete;T& operator=(T&&) =delete,但我不建议这样做.相反,添加一个正确工作的移动构造函数并移动assignemnt.它们往往容易,而且非常有用.