【问题标题】:Inverting type erasure, i.e. get types back afterwards反转类型擦除,即之后取回类型
【发布时间】:2015-06-23 09:39:48
【问题描述】:

我有一个相当通用的工作队列。它需要一定数量的std::function<void(void)> 并在 N 个工作线程上执行它们。闭包 + 类型擦除效果很好。

但是,现在我希望函数“返回”某些状态,并且我希望队列对可能的类型一无所知。为此,我正在考虑使用一个队列

std::function <std::function<void(void)>(void)>

如果我可以保持语法正确的话,它是一个接受 void 并返回一个接受 void 并返回 void 的函数。想法是添加第二个工作队列以返回任务执行的结果。

虽然这并不能严格解决问题 - 然后我可以调用返回的值,但这显然不允许我检索状态。

我可以返回 boost::any,它似乎没有告诉我包含的类型是什么,或者 boost::variant,这意味着为任务库提供所有可能返回类型的列表。两者似乎都不理想。

我想做的是对解释函数调用结果所需的信息进行编码,但我没有看到实现此目的的干净方法。将一个 execute() 和一个 extract() 方法捆绑到一个 void(void) 函子中,这超出了我的狡猾。

另一种解决方法是异构工作队列,但是用 C++ 编写这样的东西也很痛苦。我感到乐观的是,有一个惯用的解决方案可以解决执行类型擦除代码导致的未知类型,但猜测搜索关键字对我来说并不顺利。指导将不胜感激。

编辑:应用程序代码的预期工作流程大纲,与工作队列/线程池层不同

  1. 构造一个或多个异步执行的任务
  2. 将任务打包为std::function&lt;/*consistent type*/&gt;
  3. 推入库提供的队列
  4. 暂时做一些其他的事情
  5. 从队列中检索某种不透明类型
  6. 将此不透明类型传递给一个函数,以计算出它的实际含义
  7. 一切从这里开始

edit:正如 cmets 中所建议的,类型擦除是双向的。 让泛型函子为:

struct functor 
{
  typedef std::function<void(void)> functype;
  functype async;
  functype result;
};

然后使用queue&lt;functor&gt; 的实例进行发送和接收。异步在远程线程上运行。当函子的一个实例返回时,我们不知道它代表什么,但是 result() 成员可以执行并且可以执行任何被认为合理的下一步。这可能就足够了。

【问题讨论】:

  • 你能详细说明调用者会做什么任意的、可能未知的状态返回类型吗?
  • @Mark B - 感谢您的提问。通常,将其传递给函数,静态访问者样式。例如。 print() 执行某种形式的猜测类型,然后调用类型特定的 print() 函数或方法。无论异步任务队列的用户喜欢什么。
  • 只需使用boost::any。它有一个type() 成员函数,它返回它所包含的东西的typeid
  • 有什么方法可以使用静态或动态多态性来防止6 需要知道具体类型?
  • @Mark B - 这是正确的提示。动态多态性之所以有效,是因为返回值都是相同的(基本)类型。所以让我们使用一致的类型,即struct {typedef std::function&lt;void(void)&gt; func; func async; func result; }; 当一个实例从线程池中返回时,我们不知道 async() 是什么,但是 result() 知道,这就足够了。太棒了:)

标签: c++


【解决方案1】:

(复制自我的评论):

与其让步骤6 知道确切的具体类型,不如使用动态或静态多态来解决您的问题?

【讨论】:

    猜你喜欢
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多