【发布时间】:2017-01-09 11:58:09
【问题描述】:
我正在使用一个签名类似于此的函数(不是我的,来自我无法控制的库):
template<typename T, typename F>
void do_async(T const&, F); // the second parameter is a callable
它通常是这样使用的
do_async(obj, [this](){ ... });
我写了一个与此类似的函数,它总是使用相同的回调 lambda:
template<typename T>
void do_async_wrapper(T obj) {
do_async(obj, [this](){ ... });
}
我的问题源于这样一个事实,因为 obj 是作为引用传递的,所以它必须保持活动状态,直到调用回调。我的函数应该处理这个问题,所以调用者不必担心对象的生命周期。这就是它按价值接受的原因。
为了让它保持活力,我想做这样的事情:
template<typename T>
void do_async_wrapper(T obj) {
do_async(obj, [this, obj{std::move(obj)}](){ ... });
}
显然,这不会(总是)按原样工作,因为引用指向不再存在的函数本地引用,而保持活动状态的引用是它的(移动)副本。
有什么建议吗?
【问题讨论】:
-
do_async使用该参数做什么?你确定它不会在内部复制吗? -
@TartanLlama 是的。库文档指定调用者有责任确保对象保持活动状态。
-
你能链接到文档吗?一种选择是
std::shared_ptr。 -
@TartanLlama 这将涉及在堆上分配另一个对象,除了 lambda 对象(我开始认为这可能是不可避免的)
-
如果异步启动器和异步任务都需要访问缓冲区,这对于
std::shared_ptr来说是一个相当不错的用例,即使是动态分配。