我有这样的方法:

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); });

09-10 03:49