- 主题:被 std::function 坑一回
嗯,缺省copyable的环境对move太不友好了。
更合理的缺省值,缺省movable, non-copyable,就成了rust。
【 在 milksea 的大作中提到: 】
: 用到回调函数,为了支持虚函数,不用模板类型参数表示回调函数,而用了 std::function 包装。结果用 lambda 表达式传参的时候,有 move 捕获变量就编译失败了。代码类似这样:
: void api(std::function<void()>&& callback)
: {
: ...................
--
FROM 58.37.58.*
这么复杂……
【 在 milksea () 的大作中提到: 】
: 用到回调函数,为了支持虚函数,不用模板类型参数表示回调函数,而用了 std::function 包装。结果用 lambda 表达式传参的时候,有 move 捕获变量就编译失败了。代码类似这样:
:
: void api(std::function<void()>&& callback)
: {
--
FROM 139.226.19.*
我觉得 api() 传 && 背离了函数指针这个语义啊。
如果你不传 &&,按说会报 p 不可复制的错误。
[p = std::move()]
这里,我觉得 [] 里面只能出现传值和 shared_ptr<>,其它的都不保险。这种回调通常是异步的,被捕获的变量跳出了当前生命周期。& 尤其不靠谱。
如果 std::function<> 被传给另外一个线程,经常也不保险。因为 [] 里面捕获的值可能会在另外一个线程里面析构。构造函数和析构函数不在同一个线程,危!
c++ lambda 坑略多。
【 在 milksea (肥了,又肥了 >>>_<<<) 的大作中提到: 】
: 这个不本质
--
FROM 60.188.58.*
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.*
太复杂了。。。。精力都耗费在语言上了。。
【 在 milksea 的大作中提到: 】
:
: 用到回调函数,为了支持虚函数,不用模板类型参数表示回调函数,而用了 std::function 包装。结果用 lambda 表达式传参的时候,有 move 捕获变量就编译失败了。代码类似这样:
:
: void api(std::function<void()>&& callback)
: {
: callback();
: }
:
: void caller()
: {
: auto ptr = std::make_unique<Foo>();
: api(\ mutable{
: p->bar();
: });
: }
:
: 按惯例,错误信息还是一下子难以看懂。最后查来查去搞明白 std::function 要求保存的可调用对象是 copy constructable 的,而加了移动的捕获变量的 lambda 就不满足了。这问题还不好绕过去,这里最后改成 shared_ptr 了。
:
: 感觉 C++ 规则多还是一言难尽。惭愧我一开始写这段代码连mutable都不知道加。
: --
:
发自「今日水木 on Mi Note 3」
--
FROM 106.38.130.*
怎么说呢,像网上的段子,某大学物理系贴着:
Here we know everything but nothing works.
c#这种语言配code monkey写代码,则是:
Everything works but nobody knows why. 一旦出了问题就瞪眼。
那个讨论被淘汰的技能的帖子,基本结论就是这种。
【 在 GoGoRoger 的大作中提到: 】
: 太复杂了。。。。精力都耗费在语言上了。。
: 发自「今日水木 on Mi Note 3」
--
FROM 124.114.151.*
对unique_ptr不太清楚的时候,我一般会release出来而不是在让它在lambda中间传递
auto up = std::make_unique<Foo>();
call([p=up.release()](){std::unique_ptr<Foo> ap(p); ap->bar();})
--
FROM 222.129.55.*
不好。最后没调用lambda,就leak。拷贝lambda并且都调用了,就double free。
auto up = std::make_unique<std::string>("hello");
if (0) {
auto f = [p=up.release()]{std::unique_ptr<std::string> ap(p);};
// leak
} else {
auto f = [p=up.release()]{std::unique_ptr<std::string> ap(p);};
auto g = f;
f();
g(); // double free
}
【 在 ble 的大作中提到: 】
: 对unique_ptr不太清楚的时候,我一般会release出来而不是在让它在lambda中间传递
: auto up = std::make_unique<Foo>();
: call([p=up.release()](){std::unique_ptr<Foo> ap(p); ap->bar();})
--
FROM 58.37.58.*
而且还得传递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.*