带有lambda的C++回调失败,返回bad_function_call
C++ callback with lambda fails with bad_function_call
我稍微修改了[1]中的回调示例,将注册移到被调用者本身,如下所示。
// To build:
// g++ -std=c++11 callback4.cpp
#include <stdio.h>
#include <functional>
//------------------------------------------------------------------------
// Callback function.
typedef std::function<int(int)> CallbackFunction;
//------------------------------------------------------------------------
// "Caller" allows a callback to be connected. It will call that callback.
class Caller
{
public:
// Clients can connect their callback with this.
void connectCallback(CallbackFunction cb)
{
printf("setting the callback..n");
m_cb = cb;
// This call works
m_cb(10);
}
// Test the callback to make sure it works.
void test()
{
printf("Caller::test() calling callback...n");
int i = m_cb(10);
printf("Result (50): %dn", i);
}
private:
// The callback provided by the client via connectCallback().
CallbackFunction m_cb;
};
//------------------------------------------------------------------------
// "Callee" can provide a callback to Caller.
class Callee
{
public:
Callee(Caller c, int i) : m_i(i), caller(c) { }
// The callback function that Caller will call.
int callbackFunction(int i)
{
printf(" Callee::callbackFunction() inside callbackn");
return m_i * i;
}
void registerCallback() {
caller.connectCallback(
[this](int i) { return this->callbackFunction(i); });
}
private:
// To prove "this" is indeed valid within callbackFunction().
int m_i;
Caller caller;
};
//------------------------------------------------------------------------
int main()
{
Caller caller;
Callee callee(caller, 5);
callee.registerCallback();
// Test the callback. This fails.
caller.test();
return 0;
}
在这里,我通过lambda表达式中的这个引用捕获Callee。但是在Caller中调用test()失败,在运行时抛出bad_function_call。但在注册时调用回调是有效的。知道为什么吗?输出如下。
正在设置回调
Callee::callbackFunction()内部回调
调用方::test()正在调用回调
在抛出"std::bad_function_call"的实例后调用terminate
what():bad_function_call
[1]http://tedfelix.com/software/c++-callbacks.html
让我们看看Callee
构造函数:
Callee(Caller c, int i) : m_i(i), caller(c) { }
在这里,您通过值传递Caller
,这意味着您复制对象。
因此,在main
函数中,变量caller
是,而不是与Callee::caller
相同。main
变量caller
尚未注册任何回调。
简单的解决方案是使用参考:
class Callee
{
public:
Callee(Caller& c, int i) : m_i(i), caller(c) { }
...
private:
...
Caller& caller;
};
一个更好的解决方案可能是重新思考设计,以及你实际上试图解决的问题,以及用例。
相关文章:
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 奇怪的结构&GCC&clang(void*返回类型)
- 架构决策:返回std::future还是提供回调
- 为什么 GetSystemMetrics (SM_CXVIRTUALSCREEN) 返回'bad'值?
- 解密文件AES_256_CBC返回"bad decrypt"错误
- fwrite 失败(返回 0,错误给出 "Bad address")