- 主题:被 std::function 坑一回
而加了移动的捕获变量的 lambda 就不满足了。
我觉得这句话是不对的.
这里lambda变得不可copyconstructable的原因是你的lambda有一个std::unique_ptr的成员变量.
你move一个int看看,就没有问题.
而且我不认为你加了mutable就可以通过编译.
因为mutable只是去掉了lambda里面unique_ptr前面那个隐式的const qualifier.
struct Foo
{
void bar()
{
}
};
void api(std::function<void()>&& callback)
{
callback();
}
void caller()
{
auto ptr = std::make_unique<Foo>();
api([p=std::move(ptr)]() mutable{
p->bar();
});
}
int main()
{
caller();
return 0;
}
我编译了一下,错误信息显示仍然是调用了unique_ptr的copy ctor,和预期相符.
In file included from /usr/include/c++/10/functional:59,
from main.cpp:1:
...
error
...
...
main.cpp:19:25: note: ‘caller()::<lambda()>::<lambda>(const caller()::<lambda()>&)’ is implicitly deleted because the default definition would be ill-formed:
19 | api([p=std::move(ptr)]() mutable{
| ^
main.cpp:19:25: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Foo; _Dp = std::default_delete<Foo>]’
In file included from /usr/include/c++/10/memory:83,
from main.cpp:2:
/usr/include/c++/10/bits/unique_ptr.h:468:7: note: declared here
468 | unique_ptr(const unique_ptr&) = delete;
| ^~~~~~~~~~
【 在 milksea 的大作中提到: 】
: 用到回调函数,为了支持虚函数,不用模板类型参数表示回调函数,而用了 std::function 包装。结果用 lambda 表达式传参的时候,有 move 捕获变量就编译失败了。代码类似这样:
: void api(std::function<void()>&& callback)
: {
: ...................
--
修改:allegro FROM 73.63.209.*
FROM 73.63.209.*
api([p=std::move(ptr)](){
p->bar();
});
p的类型是auto p = std::move(ptr)的p的类型.
auto的推导规则会忽略&&, p的类型就是ptr的类型.
所以这个lambda有这个成员变量: const std::unique_ptr p;
【 在 allegro 的大作中提到: 】
: 而加了移动的捕获变量的 lambda 就不满足了。
: 我觉得这句话是不对的.
: 这里lambda变得不可copyconstructable的原因是你的lambda有一个std::unique_ptr的成员变量.
: ...................
--
FROM 73.63.209.*
lambda是c++的语法糖部分,不是黑魔法部分.
语法糖部分仍然是ctor/dtor/ref这些.
【 在 hongdiao 的大作中提到: 】
:
: “lambda有这个成员变量: const std::unique_ptr p”
: 你这种阐述方式我倒是第一次见,我一直只是觉得捕捉变量之后只是这个名字能在lambda里面用而已,但是你直接说成lambda的成员变量似乎更加形象。
--
FROM 158.140.1.*
我默认楼主是省略了很多东西,导致代码这么反常的传&&引用.
【 在 hgoldfish 的大作中提到: 】
: 我觉得 api() 传 && 背离了函数指针这个语义啊。
: 如果你不传 &&,按说会报 p 不可复制的错误。
: [p = std::move()]
: ...................
--
FROM 158.140.1.*
而且还得传递std::unique_ptr的deleter的支持.
我不认为release出裸指针是个好想法.
【 在 ilovecpp 的大作中提到: 】
: 不好。最后没调用lambda,就leak。拷贝lambda并且都调用了,就double free。
: auto up = std::make_unique<std::string>("hello");
: if (0) {
: ...................
--
FROM 73.63.209.*