移动lambda:一旦您捕获了仅移动类型,就如何使用lambda? [英] Moving a lambda: once you've move-captured a move-only type, how can the lambda be used?
问题描述
此答案说明了如何在C ++ 14中的lambda中移动捕获变量.
This answer explains how to move-capture a variable within a lambda in C++14.
但是一旦您在Lambda中移动捕获了不可复制的对象(例如std::unique_ptr
),就无法复制Lambda本身.
But once you've move-captured an un-copyable object (such as a std::unique_ptr
) within a lambda, you cannot copy the lambda itself.
如果您可以移动 lambda,这会很好,但是尝试这样做时出现编译错误:
This would be fine if you could move the lambda, but I get a compile error when trying to do so:
using namespace std;
class HasCallback
{
public:
void setCallback(std::function<void(void)>&& f)
{
callback = move(f);
}
std::function<void(void)> callback;
};
int main()
{
auto uniq = make_unique<std::string>("Blah blah blah");
HasCallback hc;
hc.setCallback(
[uniq = move(uniq)](void)
{
std::cout << *uniq << std::endl;
});
hc.callback();
}
这会导致g++
出现以下错误(我尝试仅复制相关行):
This produces the following error with g++
(I've attempted to copy only the relevant line):
error: use of deleted function ‘main()::<lambda()>::<lambda>(const main()::<lambda()>&’
...我认为这意味着我尝试移动lambda的尝试失败了.
...implying, I think, that my attempt to move the lambda has failed.
clang++
给出了类似的错误.
我尝试显式move
设置lambda(即使它是一个临时值),但这没有帮助.
I tried explicitly move
ing the lambda (even though it's a temporary value), but that did not help.
编辑:以下答案充分解决了上述代码产生的编译错误.对于另一种方法,只需将唯一指针的目标值release
放入std::shared_ptr
中,就可以将其复制 . (我不是将其写为答案,因为这会假定这是一个XY问题,但是必须理解为什么unique_ptr
不能用于转换为std::function
的lambda中的根本原因. )
The answers below adequately address the compile errors produced by the above code. For an alternate approach, simply release
the unique pointer's target value into a std::shared_ptr
, which can be copied. (I'm not writing this as an answer, because that would assume that this is an XY problem, but the underlying reason why unique_ptr
can't be used in a lambda that gets converted to a std::function
is important to understand.)
很有趣的是,据我所知,我只是意识到auto_ptr
实际上会在这里做正确的事情(!).它的行为本质上与unique_ptr
相似,但允许复制构造代替move-construction.
EDIT 2: Hilariously enough, I just realized auto_ptr
would actually do the right thing here (!), as far as I can tell. It acts essentially like unique_ptr
, but allows copy-construction in place of move-construction.
推荐答案
您可以移动 lambda ,很好.但这不是您的问题所在,您正在尝试使用不可复制的lambda实例化std::function
.还有:
You can move the lambda, that's fine. That's not what your problem is though, you're trying to instantiate a std::function
with a noncopyable lambda. And the:
template< class F >
function( F f );
function
的
构造函数执行:
constructor of function
does:
5)使用
f
的副本初始化目标.
5) Initializes the target with a copy of
f
.
这是因为 std::function
:
满足CopyConstructible和CopyAssignable的要求.
satisfies the requirements of CopyConstructible and CopyAssignable.
由于function
必须是可复制的,因此您放入其中的所有内容也必须是可复制的.并且只能移动的lambda不满足该要求.
Since function
has to be copyable, everything you put into it must also be copyable. And a move-only lambda does not meet that requirement.
这篇关于移动lambda:一旦您捕获了仅移动类型,就如何使用lambda?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!