在数据结构中存储成员函数

Storing member functions in a data structure

本文关键字:成员 函数 存储 数据结构      更新时间:2023-10-16

我有一个类Configuration将一些浮点参数作为映射中的键值对保存(键是字符串)。用户可以使用成员函数Configuration::set(string, float)设置参数,并使用相应的 getter 函数检索值。

作为评论,用户是我。这只是我的框架在内部使用的一个帮助程序类,不向用户公开。

棘手的部分是,对于其中一些参数,setter 函数不仅必须将键值对添加到映射中,还必须执行其他简单的操作。例如,当用户设置参数"dt"时,该方法还应计算参数"dtr"并将其设置为dtr = 1.f / dt。这只发生在少数参数上,绝大多数不需要任何特殊操作。

需要特殊操作的参数是事先知道的,并且可以安全地进行硬编码。理论上,set 函数可以有这样的实现(伪代码):

set(key, value):
    values.store(key, value)
    if key == "dt"
         values.store("dtr", 1/dt)
    else if key == "..."
         ...
    else if ...
         ...
    endif
end set

现在,这非常丑陋,并且使类的可扩展性不如我希望的(假设将来我可能想要存储浮点以外的其他参数)。所以我想我可以存储第二个包含键操作对的映射,其中每个键都有一个必须执行的相应附加操作,存储为函数指针。那么二传手的伪代码将是:

set(key, value):
    values.store(key, value)
    if key in actions
        actions[key](value)
    endif
end set

此时我所需要的只是:

  • Configuration 类中定义成员函数以具有操作
  • 在数据结构(如 std::map

后一点对我来说很晦涩。有没有便携式方法可以做到这一点?

还有另一个问题存在类似问题:存储指向任何成员函数的函数指针。在这两种情况下,问题都可以用观察者模式来解决,但就我而言,这有点矫枉过正。我所需要的只是一组非常小的函数。我宁愿不要用基类来污染我的代码,而是为所有需要特殊操作的参数对其进行子类化。在这一点上,原始if / else if的东西会更好。

您可以采用如下方法:

首先定义一个可变参数类型来保存该值,例如:

typedef boost::variant<int, float, double> value_type;

现在将地图定义为:

typedef std::map<std::string, std::pair<value_type, std::function<void(const value_type&)>> map_type;

现在当你有新类型时,展开value_type以支持它,所需的粘附代码应该更易于管理。