如何通过std::move将std::vector移入Lambda函数?
如何通过std::move将std::vector移入Lambda函数?
我完全懂你的需求:你想让lambda直接接管vector的所有权,而不是复制一份,这样main里的原vector会立刻处于空(或可安全复用的有效状态),就像用std::move给普通函数传参一样的效果。
你之前手动调用integers.clear()的方式,本质是先复制了一份vector给lambda,再手动清空原容器——既浪费了复制的性能,也不是真正的所有权转移。咱们用C++14及以后支持的初始化捕获(广义lambda捕获)就能完美解决这个问题。
正确的实现代码
#include <iostream> #include <functional> #include <vector> #include <cstdio> int main() { std::vector<int> integers = {0, 1, 2}; // 通过初始化捕获,用std::move转移vector所有权到lambda std::function<void()> lambda = [integers = std::move(integers)]() { printf("vector size (in lambda function): %zu\n", integers.size()); }; printf("vector size (in main()): %zu\n", integers.size()); // 原vector已被移动,此处输出0 lambda(); // lambda内的vector仍保留原大小3 return 0; }
为什么这样可行?
[integers = std::move(integers)]这个捕获逻辑会在lambda内部创建一个成员变量integers,并通过std::move把main中原vector的所有权直接转移给它。- 移动完成后,main里的原
integers会处于有效但未指定的状态(绝大多数STL实现中,移动后的vector会变成空的,size为0),你可以安全销毁它或者重新赋值。 - 这种方式避免了复制整个vector的开销,尤其适合存储大量数据的vector场景。
如果你用的是C++11(不支持初始化捕获)怎么办?
C++11没有直接的移动捕获语法,但可以用个小技巧绕开:把vector包装在std::unique_ptr里(unique_ptr只能移动不能复制),通过捕获智能指针间接实现所有权转移:
#include <iostream> #include <functional> #include <vector> #include <memory> #include <cstdio> int main() { auto integers = std::make_unique<std::vector<int>>({0, 1, 2}); std::function<void()> lambda = [integers]() { printf("vector size (in lambda function): %zu\n", integers->size()); }; printf("vector size (in main()): %zu\n", integers ? integers->size() : 0); // 原指针已被移动,输出0 lambda(); return 0; }
不过这种方式会多一层指针开销,所以能升级到C++14及以上的话,优先用第一种初始化捕获的方式。
备注:内容来源于stack exchange,提问作者Rahn
相关产品推荐
相关产品推荐

