c++ - 如何设计一个 "Awaitable"基类?

标签 c++ templates c++17 virtual-functions multidispatch

许多地方的 C++ 标准库提供了一种“可等待”的 API:例如std::futurestd::condition_variable可以立即“尝试”获得他们的值(value),无限期地“等待”他们的值(value),“wait_for”某个std::chrono::duration ,或“wait_until”某个std::chrono::time_point到达了。我正在努力创建一个捕获这些相同操作的抽象基类。

template <typename T>
class awaitable {
 public:
  virtual std::optional<T> try() = 0;

  virtual std::optional<T> wait() = 0;

  template <typename Rep, typename Period>
  virtual std::optional<T> wait_for(const std::chrono::duration<Rep, Period>&) = 0;

  template <typename Clock, typename Duration>
  virtual std::optional<T> wait_until(const std::chrono::time_point<Clock, Duration>&) = 0;
};
trywait没有问题。 wait_forwait_until需要模板参数,因此不能是虚拟的。
有没有一种“干净”的方式来定义这样的接口(interface)?`
我考虑过的一些选项(除非我遗漏了什么)似乎不可行:
  • 使用 std::any或其他类型的删除。在内部传递 duration 时反对另一个函数,我仍然需要知道正确的类型才能正确转换它。
  • 使用访问者模式。这将要求我在一个中心位置指定从“Awaitable”派生的所有类型的硬编码列表,引入循环依赖并限制可扩展性。
  • 使用 std::duration_caststd::time_point_cast将任何传入类型类型转换为 std::chrono::nanosecondsstd::chrono::time_point<std::chrono::high_resolution_clock> ,所以会有一个非虚拟模板化方法和一个虚拟非模板化方法。这似乎会引入不必要的开销和潜在的不当行为,因为我不确定是否保证每种可能的传入类型都可以转换为这些常见类型。

  • 到目前为止,第三种变体似乎是我唯一的选择,而不是一个很好的选择。

    最佳答案

    我认为你的第三种方式可能是要走的路。有疑问,您必须付出一些努力来限制可能的误用。
    您还可以查看非循环访问者模式:
    https://en.wikipedia.org/wiki/Visitor_pattern
    Acyclic Visitor C++
    对于某些场景,Andrei Alexandrescu 提供的实现方式(真的可以推荐他的书)对我帮助很大。它需要一些努力才能完全理解,有点侵入性,据我所知,至少对于 C++ < 14,不可能在这里保持 100% 的宏免费,但它具有你可能需要的去中心化的巨大优势。此外,对于大多数用例和现代架构来说,它的次要 dynamic_cast-usage(不被误用作动态开关)并不是真正的问题。

    关于c++ - 如何设计一个 "Awaitable"基类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65087134/

    相关文章:

    c++ - std::ofstream 不接受 << 运算符的 const char *

    visual-studio - Visual Studio 模板 - 有条件隐藏参数

    c++ - 简单的模板继承问题C++

    c++ - 检测std::shared_ptr持有原始数组(并获取其大小)

    c++ - 折叠表达式和参数包 : difference betwen Args&& and Args inside static_assert

    c++ - 表达式未评估为常量两级 constexpr 函数(编译器错误?)

    c++ - 如何返回作用域锁?

    c++ - 通过网络广播服务器存在

    c++ - CMake 未将 boost 目录包含在其生成的项目中

    c++ - 如何在整数列表中找到缺失的元素?