- 主题:被 std::function 坑一回
用到回调函数,为了支持虚函数,不用模板类型参数表示回调函数,而用了 std::function 包装。结果用 lambda 表达式传参的时候,有 move 捕获变量就编译失败了。代码类似这样:
void api(std::function<void()>&& callback)
{
callback();
}
void caller()
{
auto ptr = std::make_unique<Foo>();
api([p=std::move(ptr)]() mutable{
p->bar();
});
}
按惯例,错误信息还是一下子难以看懂。最后查来查去搞明白 std::function 要求保存的可调用对象是 copy constructable 的,而加了移动的捕获变量的 lambda 就不满足了。这问题还不好绕过去,这里最后改成 shared_ptr 了。
感觉 C++ 规则多还是一言难尽。惭愧我一开始写这段代码连mutable都不知道加。
--
FROM 120.36.49.*
这个不本质
【 在 hgoldfish 的大作中提到: 】
: std::function 我把它当成指针看。。
:
: 就好像 shared_ptr<> 一样,你不需要用 && 或者 & 来优化。
: ...................
--
FROM 120.36.49.*
可是标准大概率不会改了
【 在 Rob 的大作中提到: 】
: 使用folly function. STD function 设计有比较大问题.
:
: 【 在 milksea () 的大作中提到: 】
: ...................
--
FROM 120.36.49.*
嗯,可能我没说清楚。我是说不加mutable还有别的问题,lamda表达式里修改参数需要mutable声明。
我遇到的问题是std::function需要copy ctor,这个没有好解法
【 在 allegro 的大作中提到: 】
: 而加了移动的捕获变量的 lambda 就不满足了。
:
: 我觉得这句话是不对的.
: ...................
--
FROM 120.36.49.*
确实是有很多考虑不周到的地方,学艺不精。
move就是传递生存期,这个从语义上预期是要支持的
【 在 hgoldfish 的大作中提到: 】
: 我觉得 api() 传 && 背离了函数指针这个语义啊。
:
: 如果你不传 &&,按说会报 p 不可复制的错误。
: ...................
--
FROM 220.249.162.*
我看到stackoverflow里面还有用shared_ptr包一层unique_ptr的处理方法,我觉得很魔道…他这个思路无非解出来就这样了吧
【 在 ilovecpp 的大作中提到: 】
: 当然可以,不过你怎么实现copy ctor?
:
: 【 在 DoorWay 的大作中提到: 】
: ...................
--
修改:milksea FROM 120.36.49.*
FROM 120.36.49.*
我没研究过,为什么folly可以不要求可拷贝而std要求,不知道有什么考虑还是std开始没想到。如果是现有版本std库缺陷,以后增加提案放宽std::function的构造需求应该是最优解。
【 在 ilovecpp 的大作中提到: 】
: 你这样的functor一样是不可拷贝,和楼主最早写的并无差别。
: 有的functor就是不可拷贝,std::function不该要求可拷贝。
:
: ...................
--
FROM 120.36.49.*
就是单纯开后门绕过语法限制吧
【 在 ilovecpp 的大作中提到: 】
: 什么场景用到shared<unique>? 我们共同拥有一个对象,但我们任何一个人都可以把它偷走...
:
: 【 在 milksea 的大作中提到: 】
: ...................
--
FROM 120.36.49.*