c++ - 移动(或复制)捕获可变参数模板参数到 lambda
问题描述
我试图弄清楚如何将可变参数参数移动(或者如果移动不可用,则仅复制)到模板化函数中的 lambda 中。
我正在使用仅移动类(见下文)对此进行测试,因为这将是需要与我的模板一起使用的“最坏情况”。
class MoveOnlyTest {
public:
MoveOnlyTest(int a, int b = 20, int c = 30) : _a(a), _b(b), _c(c) {
std::cout << "MoveOnlyTest: Constructor" << std::endl;
}
~MoveOnlyTest() {
std::cout << "MoveOnlyTest: Destructor" << std::endl;
}
MoveOnlyTest(const MoveOnlyTest& other) = delete;
MoveOnlyTest(MoveOnlyTest&& other) :
_a(std::move(other._a)),
_b(std::move(other._b)),
_c(std::move(other._c))
{
std::cout << "MoveOnlyTest: Move Constructor" << std::endl;
other._a = 0;
other._b = 0;
other._c = 0;
}
MoveOnlyTest& operator=(const MoveOnlyTest& other) = delete;
MoveOnlyTest& operator=(MoveOnlyTest&& other) {
if (this != &other) {
_a = std::move(other._a);
_b = std::move(other._b);
_c = std::move(other._c);
other._a = 0;
other._b = 0;
other._c = 0;
std::cout << "MoveOnlyTest: Move Assignment Operator" << std::endl;
}
return *this;
}
friend std::ostream& operator<<(std::ostream& os, const MoveOnlyTest& v) {
os << "{a=" << v._a << "}";
return os;
}
private:
int _a;
int _b;
int _c;
};
这是我试图开始工作的测试代码:
void test6() {
std::cout << "--------------------" << std::endl;
std::cout << " TEST 6 " << std::endl;
std::cout << "--------------------" << std::endl;
MoveOnlyTest v(1, 2, 3);
test6_A(std::move(v));
}
void test6_A(MoveOnlyTest v) {
std::cout << "test6_A()" << std::endl;
test6_B(test6_C, v);
}
template <typename ... ARGSF, typename ... ARGS>
void test6_B(void(*fn)(ARGSF...), ARGS&&... args) {
std::cout << "test6_B()" << std::endl;
//What do I need to get args to be moved/copied into the lambda
auto lambda = [fn, args = ???]() mutable {
(*fn)( std::forward<ARGS>(args)... );
};
lambda();
}
void test6_C(MoveOnlyTest v) {
std::cout << "test6_C()" << std::endl;
std::cout << "v = " << v << std::endl;
}
我试图具有与下面完全相同的行为,仅使用通用模板,以便我可以创建一个捕获和参数的 lambda,并使用这些参数调用任何函数。
void test5() {
std::cout << "--------------------" << std::endl;
std::cout << " TEST 5 " << std::endl;
std::cout << "--------------------" << std::endl;
MoveOnlyTest v(1, 2, 3);
test5_A(std::move(v));
}
void test5_A(MoveOnlyTest v) {
std::cout << "test5_A()" << std::endl;
auto lambda = [v = std::move(v)]() mutable {
test5_B(std::move(v));
};
lambda();
}
void test5_B(MoveOnlyTest v) {
std::cout << "test5_B()" << std::endl;
std::cout << "v = " << v << std::endl;
}
需要明确的是,我不想像c ++ lambdas中那样完美地捕获参数如何从上层范围捕获可变参数包我想尽可能移动它们,如果没有,复制它们(原因是我计划存储这个 lambda 以供以后执行,因此如果它们只是通过引用捕获,堆栈中的变量将不再存在)。
解决方案
需要明确的是,我不想像在 c++ lambdas 中那样完美地捕获参数如何从上层范围捕获可变参数包我想尽可能移动它们
只需使用相同的形式:
auto lambda = [fn, ...args = std::move(args)]() mutable {
(*fn)(std::move(args)...);
};
在 C++17 中,你可以这样做:
auto lambda = [fn, args = std::tuple(std::move(args)...)]() mutable {
std::apply([fn](auto&&... args) { (*fn)( std::move(args)...); },
std::move(args));
};
推荐阅读
- docker - docker 容器端口在第一次连接后关闭
- azure - Azure B2C 使用自动生成的注册用户名设置客户策略
- mysql - 获取所有供应商生成的零件
- jquery - 在 TypeScript 中管理可排序的 JQueryUI
- google-cloud-dataflow - 如何从数据流作业中发送和过滤结构化日志
- python - PYthon 和 Appium:如何转到父元素
- python - 使用 Python Click 创建分层命令
- javascript - 加载脚本和清单违反了内容安全策略指令
- java - 运行本机查询时发生 ConverterNotFoundException
- android - 如何确定 GMail 用于传递我的应用程序接收到的文件的 MimeType?