将捕获的可变参数移动(或复制)到lambda中



我试图弄清楚如何移动(或只是复制,如果移动不可用)可变参数到一个模板化函数内的lambda。

我正在用一个move-only类(见下文)来测试它,因为这将是"最坏情况"。这需要与我的模板工作。

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;
}

说明一下,I我想在可能的情况下移动它们,如果不能,复制它们(原因是我计划存储这个lambda以供以后执行,因此堆栈中的变量将不再存在,如果它们只是通过引用捕获)。

需要说明的是,我不想像c++那样完美地捕捉参数如何从上层作用域捕获可变参数包I如果可能的话想要移动它们

只是使用相同的形式:

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));
};

相关内容

  • 没有找到相关文章

最新更新