【发布时间】:2017-07-09 17:30:01
【问题描述】:
立即回调
考虑以下示例:
template <typename lambda> void call_me_back(const lambda & callback)
{
// Very complicated calculation to find the meaning of everything
callback(42);
}
int main()
{
call_me_back([](const int & value)
{
std :: cout << value << std :: endl;
});
}
在这里,我为call_me_back 提供了一个接受int 的lambda。 call_me_back 在经过长时间的计算后调用 callback,然后 callback 将其打印出来。像蛋糕一样简单。
现在,假设根据执行情况,call_me_back 需要使用 int 或其他类型调用 callback。我们可以将前面的示例编辑为
template <typename lambda> void call_me_back(const lambda & callback)
{
// Very complicated calculation to find the meaning of everything
if(rand() % 2)
callback(42);
else
callback("Kill all the humans.");
}
int main()
{
call_me_back([](const auto & value)
{
std :: cout << value << std :: endl;
});
}
到目前为止一切顺利。现在callback 可以做各种花样并根据其类型处理value。
延迟回调
现在,回到第一个例子。假设call_me_back 尚未准备好立即使用int 调用callback。然而,它可以做的是将callback 存储到某个地方,然后再调用它。
例如:
std :: function <void(const int &)> the_callback;
template <typename lambda> void call_me_back(const lambda & callback)
{
the_callback = callback;
}
void ready_to_answer()
{
the_callback(42);
}
int main()
{
call_me_back([](const auto & value)
{
std :: cout << value << std :: endl;
});
}
现在,call_me_back 不是立即调用callback,而是将callback 存储在std :: function <void(const int &)> 对象中(我知道,它在全局范围内,请耐心等待)。然后可能会发生很多事情,并且在某些时候有人可以调用ready_to_answer,它会检索先前存储的回调并调用它。例如,ready_to_answer 可以被另一个线程调用,但是有很多原因需要这样的范例,回调可以存储并在以后调用。
问题
如果我想实现第二个示例,但回调有延迟怎么办?。我似乎无法理解这一点。
我可以想象std :: function 是使用接受某些特定类型的虚拟调用运算符实现的。 std :: function 然后包装一个指向模板包装类的指针/引用,该模板包装类存储实际的 lambda 并通过将其参数转发到它正在存储的 lambda 来实现调用运算符。好,易于。 但我不能有模板虚方法!
我尝试过想出各种解决方案,但找不到任何可行的方法。这真的不可能吗?是否不可能有一些外部提供的 lambda 接受存储在某处的 const auto & 参数,然后再调用它?
【问题讨论】:
标签: c++ templates lambda auto generic-lambda