【问题标题】:boost::future::then how is it implemented?boost::future::那么它是如何实现的呢?
【发布时间】:2019-12-25 07:24:08
【问题描述】:

我在其他语言(javascript、python)中大量使用期货,尤其是延续(当时),最近了解到类似的东西也可以在 c++ 中使用。比如这样:

#include <iostream>
#include <string>
#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#include <boost/thread/future.hpp>
using namespace boost;

int main() {
    future<int> f1 = async ([]() { sleep (1); return 123; });
    future<std::string> f2 = f1.then ([](future<int> f) {
        std::cout << f.get() << std::endl;
        sleep (1);
        return std::string ("foo");
    });
    f2.then ([](future<std::string> f) {
        std::cout << f.get () << std::endl;
    });
    sleep (3);
}

我的目标是了解这是如何实现的,所以我在这里查看:
https://github.com/boostorg/thread/blob/develop/include/boost/thread/future.hpp.
发生了很多事情,我想我理解了其中的大部分内容,但是关于所有这些模板魔法的一些具体细节我不理解,也无法在代码中找到。

f1.then() 被调用时,它会根据回调的返回类型创建一个新的future (f2)。如果我理解正确,回调实际上存储在 f2.当 f1 设置一个结果时,它“激活” f2 反过来调用回调并使用返回值来设置它自己的结果。我认为相关电话发生在这里:
https://github.com/boostorg/thread/blob/develop/include/boost/thread/future.hpp#L4500
似乎 f2 内部有一个 continuation_shared_state ,其中包含对 f1 (父)的引用,但我不明白这是如何完成的。 f2 的类型只是future&lt;std::string&gt; 而不是future&lt;std::string, int&gt;future&lt;std::string, future&lt;int&gt;&gt;。父 future 的类型不是新 future 类型的一部分,但它仍然存储在其中。这是怎么做到的?

谢谢!

【问题讨论】:

  • 您的问题不应依赖外部链接来完成。此外,您需要首先减少问题:将所有相关代码从标头复制到文件中(解决 #include 语句),然后通过将模板参数替换为实际类型并明确删除不必要的代码来开始减少事情。此外,使用调试器单步调试代码以了解其工作原理。
  • 我理解,但我的问题实际上与提升实施甚至未来无关。我的最后一句话陈述了关于模板的问题——>我只是试图给出一些上下文。减少代码当然是一个有效的解决方案,如果没有人可以回答这个问题,实际上是我唯一的选择。

标签: c++ templates boost


【解决方案1】:

这是通过一种称为“类型擦除”的技术完成的。
这不是在 boost 实现中实际完成的方式,而是基本上:
f2 包含一个对象,它是一个非模板类型,它具有在派生模板类型中实现的虚拟方法。这个派生的模板类型取决于“当前”未来和父未来的类型 --> 这意味着它保持f1f2 之间的链接,而两者中的任何一个都不会直接相互了解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    相关资源
    最近更新 更多