std::包含 std::函数回调的多个包装器的向量不起作用
std::vector of multiple wrappers containing std::function callbacks does not work
我正在编写一个包含 std::function<> 的包装器MyTest
,用于存储回调。 包装器包含在 shared_ptr<> 的 std::vectortests
中。 emplace_back向量中的单个包装器有效,即可以触发 std::function 回调。如果我在向量中有两个对象,则只有最后一个对象回调有效。
以下是我的课程:
typedef function<void(const uint64_t &)> CallBackFunc_t;
class MyWheel
{
private:
class test
{
private:
const CallBackFunc_t &callback;
public:
test(const CallBackFunc_t &cb);
bool work();
};
public:
vector<shared_ptr<test>> tests;
int addTest(const CallBackFunc_t &test_callback);
void spin(void);
};
class MyTest
{
private:
int handle = -1;
MyWheel &wheel;
public:
MyTest(MyWheel &whl);
int setCallback(const CallBackFunc_t &callback);
};
和来源。
MyWheel::test::test(const CallBackFunc_t &cb) : callback(cb)
{
}
bool MyWheel::test::work()
{
callback(0);
return true;
}
int MyWheel::addTest(const CallBackFunc_t &test_callback)
{
tests.emplace_back(new test(test_callback));
return (int)(test.size()-1);
}
void MyWheel::spin(void)
{
for(vector<shared_ptr<test>>::iterator test = tests.begin(); test != tests.end(); ++test)
{
(*test)->work();
}
}
MyTest::MyTest(MyWheel &whl) : wheel(whl)
{
};
int MyTest::setCallback(const CallBackFunc_t &callback)
{
if(handle < 0)
{
handle = wheel.addTest(callback);
}
return handle;
}
用法:
MyWheel wh;
MyTest t1(wh);
MyTest t2(wh);
t1.setCallback([&](const uint64_t &e) {
cout <<"1rn";
});
t2.setCallback([&](const uint64_t &e) {
cout <<"2rn";
});
while(true)
{
wh.spin();
}
我希望在运行时打印"1"和"2",但只有"2"是...... 我做错了什么?
你需要通过复制存储回调:
class test
{
private:
CallBackFunc_t callback; // <---- make a copy of callback
public:
test(const CallBackFunc_t &cb);
bool work();
};
现在你有未定义的行为,因为你正在存储对回调的引用,该回调在此表达式的末尾被销毁:
t1.setCallback([&](const uint64_t &e) {
cout <<"1rn";
}); // it causes dangling reference
如果你想在test
中保留对回调的引用,你需要在调用setCallback
之前将它们创建为Lvalues:
std::function<void (const uint64_t& )> callback1 = [](const uint64_t &e) {
cout <<"1rn";
};
t1.setCallback(callback1);
std::function<void (const uint64_t& )> callback2 = [](const uint64_t &e) {
cout <<"2rn";
};
t2.setCallback(callback2);
嗨,rafix07,感谢您的示例! 是的,这确实起到了作用,并且在捕获列表中添加 & 使得访问定义回调函数的变量成为可能。
即
bool var1 = false;
std::function<void (const uint64_t& )> callback1 = [&](const uint64_t &e) {
cout <<"1rn";
var1 = true;
};
t1.setCallback(callback1);
相关文章:
- std::向量与传递值的动态数组
- 如何在旧c++中初始化const-std向量
- 如何检查两个 std::向量在小于 O(n) 的时间复杂度内是否相等
- 当键值是 std 向量时,为什么使用 at in C++ 访问映射值如此缓慢?
- 如何初始化 std::向量的映射?
- 迭代时将指向differents类型的指针保存在std::向量中
- std::向量迭代器和调整大小/保留的奇怪/有趣行为
- yaml-cpp到std::向量迭代的怪异行为
- 故意泄漏std::向量的内存
- 调整STD ::向量的大小是否可以降低其能力
- std ::向量距离函数如何给出比.size()更高的值
- C++ std::向量插入两个元素替代算法失败
- 错误:数字常数之前的预期无限制ID:std :: array和std ::向量大小分配
- 在我提供的此示例中,如何将2维std ::向量的逻辑更改为具有向量[row] [col] [col] [col] [co
- GUI滑块的动态数量,该数量更新具有回调中值的std ::向量
- 是一个std ::向量线程,我的目的是安全的
- 将具有std ::向量的C 函数称为Julia的输入和输出参数
- 将std ::向量作为指针参考
- STD ::向量如何调整其内部缓冲区大小
- 在C 中,是否有可能在不兼容类型的std ::向量对象之间传输不同类型的缓冲区