【问题标题】:Typesafe callback system in modern C++现代 C++ 中的类型安全回调系统
【发布时间】:2011-10-24 08:05:43
【问题描述】:

我正在处理一个使用回调系统的模块,该系统实现得不是很好。客户端正在使用一个 ID 注册,并将使用一个变量(或两个,或无)回调。问题是几乎每个 ID 都是不同的变量。 (例如:Id1 -> char*,Id2 -> int)。这是通过通过指针传递变量来实现的。所以回调看起来像

typedef void (*NotifFunctionPtr)(void* ctx, const void* option);

这种方法有很多问题,我想用一种(类型)安全且现代的方式来处理它。然而这并不像看起来那么简单,我有一些想法(like boost::function 或用封装类型和 ptr 的结构替换 void*)但我认为也许有更好的想法,所以我想知道 在 C++ 中设置类型安全回调的现代方法是什么。

编辑:另一个想法是通过模板函数注册一个类型为 T 的回调,该模板函数使用相同的类型 T 进行回调。这是否可行或在某个库中实现?

【问题讨论】:

    标签: c++ templates boost callback


    【解决方案1】:

    您的问题不在于回调,而是您希望将所有回调视为相同类型,而实际上它们不是(签名不同)。因此,要么你使用讨厌的 C void* 技巧,要么如果你想使用 type-safe 方法,你将不得不为此付费,并提供不同的方法来注册不同的回调类型——这恕我直言是正确的方法。

    一旦你解决了这个问题,你就可以使用signalssignals2 库,或者使用function 作为基础来实现你自己的轮子(以避免重写类型擦除)。

    【讨论】:

    • 还有一个用boost::any替换空指针的选项。我当然会建议在任何使用 ID 的东西上使用单独的信号(使用 boost 或 sigc++),但如果这么多的重构不可行,boost::any 至少允许在运行时检查您是否获得了正确的类型。
    • @JanHudec: 是的,确实如此,boost::any 将提供 type-safe 解决方案 at runtime,即不会失败编译,但如果您传递错误类型的参数,则无法执行。仍然比 void* 和/或如果您未能匹配类型会默默地导致 UB 的联合好得多。
    • 如果模板函数注册一个类型为T 的回调并使用相同类型的T 回调。
    • @cprogrammer:我在考虑比单个函数调用更长寿的回调,在这种情况下,您的建议的问题是如何存储它们(需要类型擦除),同时能够安全地知道以后以类型安全的方式传递哪些参数。
    • 是的,这不是我所要求的类型安全,但垃圾将在回调类中。不一定是个好主意。
    【解决方案2】:

    boost::function 正是这里的正确选择。您无需过多更改代码即可获得函数对象的类型安全性。

    【讨论】:

      【解决方案3】:

      如果您已经研究过 boost。为什么不使用signalssignals2 库。

      【讨论】:

      • 不知道用不同的数字参数能否解决问题。
      猜你喜欢
      • 2011-08-06
      • 1970-01-01
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多