多态性在 lambda 函数C++不起作用
Polymorphism doesn't work in C++ lambda function
我有这样的方法:
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));
}
但是在第两种情况(asyncOperation(ProgressCallback&)
)中progressCallback
的行为不是多态的,它总是调用基类的方法,这绝对不是我所期望的。所以我的问题是:1)为什么会发生这种情况,2)如何解决它(是的,我知道我可以停止使用lambdas,但也许有一些传统的解决方法)?
你显示的代码没有多态的空间,但让我们假设asyncOperation
传递了一个对派生自ProgressCallback
的东西的引用:
当您将引用传递给bind
时,您正在创建副本。 绑定返回的对象根据它所包含的有关它的类型信息存储值。 它只知道它有对ProgressCallback
的引用,所以这就是它存储的值。 这会导致切片副本。
您需要将值包装在reference_wrapper中:
jobsPool.addJob(bind(impl, ref(progressCallback));
或者你可以使用lambda(更好):
jobsPool.addJob([impl,&progressCallback](){ impl(progressCallback); });
或者,您可以创建impl
,以便它自己完成所有操作。
您现在正在执行的操作相对等效于:
jobsPool.addJob([impl,=progressCallback]() mutable { impl(progressCallback); });
你不需要定义一个lambda,然后使用绑定,或者使用两个lambda,你可以一次性完成这一切:
void asyncOperation(ProgressCallback& progressCallback)
{
jobsPool.addJob([&] { syncOperation(progressCallback); });
}
如前所述,在原始代码中,由于正在发生的切片副本,您被咬了。由于模板参数推导的工作原理,延迟函数调用(如std::bind
)需要通过引用包装器传递引用参数。这种相当奇怪的行为是另一个很好的理由,一旦您可以访问 lambda,就根本不使用bind
。但请注意,此行为也适用于std::thread
。
请注意,存储通过引用捕获某些内容的 lambda 是一件非常危险的事情。您可以使用 progressCallback 对象调用asyncOperation
,该对象随后处于活动状态,并且该对象可能在执行 lambda 时被破坏,从而导致未定义的行为。
- 我的神经网络不起作用 [XOR 问题]
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- C++为什么尽管我调用了void函数,它却不起作用
- 为什么在保护模式下继承升级不起作用
- 循环在计数器中不起作用
- 在其他文件中创建类时在 c++ 项目中不起作用
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 为什么二进制搜索在我的测试中不起作用
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- Bjarne Stroustrup Book - std_lib_facilities.h - 不起作用(未知类型名称)
- 为什么简单的算术减法在"if"条件下不起作用?
- 为什么Stroustup书中的has_f不起作用
- 你能检查一下为什么在这个代码中从链接列表中删除项目不起作用吗
- 嵌套While循环不起作用(C++问题)
- C++Matching Brackets 2解决方案不起作用
- 为什么这段代码不起作用,我该如何解决?
- 我正在开发服务器,ip作为参数传递不起作用