C++如何将可变模板参数移动/复制到lambda中供延后执行
解决方案
你需要使用C++17引入的可变参数初始化捕获特性实现需求,补全后的test6_B模板代码如下:
template <typename ... ARGSF, typename ... ARGS> void test6_B(void(*fn)(ARGSF...), ARGS&&... args) { std::cout << "test6_B()" << std::endl; // 可变参数初始化捕获,优先移动、不可移动时自动回退到复制 auto lambda = [fn, ...args = std::forward<ARGS>(args)]() mutable { (*fn)( std::forward<ARGS>(args)... ); }; lambda(); }
实现说明
...args = std::forward<ARGS>(args)是C++17支持的参数包初始化捕获语法,会对每个参数单独处理:- 传入参数为右值时,
std::forward返回右值引用,触发移动构造将值转移到lambda内部存储 - 传入参数为左值时,
std::forward返回左值引用,触发拷贝构造将值复制到lambda内部存储
- 传入参数为右值时,
- 所有参数都以值的形式持有在lambda对象中,完全脱离原函数栈上下文,即使延后执行也不会出现悬空引用问题
- 调用目标函数时的
std::forward<ARGS>(args)...会保持参数的原始值类型,行为和你给出的test5示例完全一致
注意事项
你当前test6_A中调用test6_B的代码会触发编译错误:
test6_B(test6_C, v); // v是左值,会尝试调用拷贝构造,但MoveOnlyTest禁止拷贝
需要改为移动语义传入:
test6_B(test6_C, std::move(v));
内容的提问来源于stack exchange,提问作者Patrick Wright
相关产品推荐
相关产品推荐

