【问题标题】:Is it possible to transform a future type?是否有可能改变未来的类型?
【发布时间】:2021-11-28 07:39:19
【问题描述】:

使用具有类似方法的库:

std::future<bool> action();

我发现自己必须遵守项目特定的enum 返回类型,例如:

enum Result { Ok, Failed, ConnectionDown, ServerError };

并且调用的动作点如下所示:

std::future<Result> act()
{
  try {
    return _actor->action(); // This returns a different type :(
    // What to do here ??? ^
  } 
  catch (ConnectionError const& e)
  {
    return std::make_ready_future<Result>(Result::ConnectionError);
  }
  catch (ServerError const& e)
  {
    return std::make_ready_future<Result>(Result::ServerError);
  }
}

所以本质上,该库没有针对错误情况的特定返回码,而是将它们作为异常发出。处理这很容易,因为我可以构建具有适当价值的现成期货。问题(具有讽刺意味)在于非异常路径,其中库的 std::future&lt;bool&gt; 必须转换为 std::future&lt;Result&gt;

.get() 结果并根据其值(true -> Ok, false -> Failed)构建一个就绪的未来是没有意义的,因为这样我就可以从我的函数中删除异步性。有没有更好的方法来处理这个问题?

【问题讨论】:

标签: c++ multithreading c++17


【解决方案1】:

等待继续函数 (std::experimental::future::then) ,你可能想要这样的东西:

std::future<Result> act()
{
    return std::async([&](){
        try {
            if (_actor->action().get()) {
                return Result::Ok;
            } else {
                return Result::Failed;
            }
        } 
        catch (ConnectionError const& e) {
            return Result::ConnectionError;
        }
        catch (ServerError const& e) {
            return Result::ServerError;
        }
    });
}

【讨论】:

  • 似乎就是这样。从您链接的问题中推断出这一点,我是否应该假设这只会在我们 .wait.get 未来时触发潜在的操作?
  • 实际上取决于调用async 的方式(使用std::launch::deferred,是的)。
猜你喜欢
  • 1970-01-01
  • 2021-03-25
  • 2012-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-06
相关资源
最近更新 更多