std::vector的元素类型是否需要可移动才能在值返回时触发移动语义?
结论
不需要,MyType 不需要是可移动类型,编译器也可以对返回的 std::vector<MyType> 应用移动语义。
原理说明
- 该场景下的移动语义作用于
std::vector容器本身,和容器内存储的MyType元素无关。std::vector的移动构造逻辑仅会转移内部堆缓冲区的所有权,本质只是交换内部的首地址指针、已用末尾指针、容量上限三个变量的值,全程不会对容器内的元素执行任何移动、拷贝操作,因此MyType是否支持移动完全不影响vector的移动操作是否合法。 - 即便MyType是不可移动、甚至不可拷贝的类型,只要你在函数内完成了
std::vector<MyType>的构造和填充,返回时依然可以正常走vector的移动逻辑,不会有编译错误。你可以参考下面的验证代码:
#include <vector> struct MyType { MyType() = default; // 显式删除拷贝、移动构造 MyType(const MyType&) = delete; MyType(MyType&&) = delete; }; std::vector<MyType> foo() { std::vector<MyType> v; v.emplace_back(); // 原地构造元素,无需拷贝/移动 return v; // 正常触发vector的移动构造,不涉及MyType的操作 } int main() { auto res = foo(); return 0; }
- 只有当vector的移动构造不可用、编译器退而选择拷贝构造时,才会要求MyType支持拷贝操作。但你给出的示例符合C++标准的「返回局部自动变量时重载决议优先选择移动构造」规则,只要没有使用自定义特殊分配器禁用vector的移动构造,就不会触发拷贝回退逻辑。
内容的提问来源于stack exchange,提问作者VladG
相关产品推荐
相关产品推荐

