我有这样的方法:
void syncOperation(ProgressCallback& progressCallback);
其中
ProgressCallback
是:class ProgressCallback
{
public:
virtual void onProgress(std::size_t currValue, std::size_t maxValue) {}
virtual void onDone() {}
};
并且我想使其异步,因此我执行以下操作:
void asyncOperation(ProgressCallback& progressCallback)
{
auto impl = [this](ProgressCallback& progressCallback_)
{
syncOperation(progressCallback_);
};
jobsPool.addJob(std::bind(impl, progressCallback));
}
但是在第二种情况下
progressCallback
的行为(asyncOperation(ProgressCallback&)
)不是多态的,它始终会调用基类的方法,这绝对不是我期望的。所以我的问题是:1)为什么会发生这种情况; 2)如何解决它(是的,我知道我可以停止使用lambda,但也许有一些传统的解决方法)? 最佳答案
您显示的代码没有多态的余地,但是让我们假设asyncOperation
传递了对从ProgressCallback
派生的东西的引用:
将引用传递给bind
时,您正在创建一个副本。绑定(bind)返回的对象根据其具有的类型信息存储值。它只知道它有对ProgressCallback
的引用,因此它就是存储的值。这将导致 slice 副本。
您需要将值包装在reference_wrapper中:
jobsPool.addJob(bind(impl, ref(progressCallback));
或者您可以使用lambda(更好):
jobsPool.addJob([impl,&progressCallback](){ impl(progressCallback); });
或者,您可以只创建
impl
,以便它自己执行所有操作。 您现在所要做的相对相当于:
jobsPool.addJob([impl,=progressCallback]() mutable { impl(progressCallback); });