boost::函数与函数指针

boost::function vs function pointers

本文关键字:函数 指针 boost      更新时间:2023-10-16

我正在实现一个通用设置阅读器。这个想法是我有一个应用程序,其设置可以是布尔值,整数和字符串。然后我有一个 Config 类,其中实现了此类设置的 getter,config 类在构造函数中获取一个客户,以便它知道它将读取该客户的设置。

我在工作时遇到了麻烦,我想我滥用了 boost::函数将其与普通函数指针混淆。

在映射中,我希望有引用,而boost::function只能在配置读取时绑定,因为我在那里为给定的客户分配了一个Config实例。

问题是我不能在没有 typedefs 的情况下使用函数指针,这使模板工作复杂化,有什么更明智的解决方案吗?

#include "Config.h"
class ConfigReader
{
    ConfigReader();
    template<class R>
    R readConfig(std::string customer, std::string settingName);
private:
        typedef bool (Config::* BoolConfigFunctor) () const;
    std::map<std::string, BoolConfigFunctor> boolConfigMap;
        typedef int(Config::* IntConfigFunctor) () const;
    std::map<std::string, IntConfigFunctor> integerConfigMap;
        typedef std::string (Config::* StrConfigFunctor) () const;
    std::map<std::string, StrConfigFunctor> stringConfigMap;
    template<class R>
    std::map<std::string, R (Config::* ) () >  getConfigMap();
}
ConfigReader()
{
    // INIT all settings you want to be readable in the functor maps
    boolConfigMap["USE_NEW_VERSION"]    = &Config::useNewVersion;
    boolConfigMap["MAINTENANCE_MODE"]   = &Config::isMaintenance;
    integerConfigMap["TIMEOUT"]         = &Config::getTimeout;
    stringConfigMap["USERNAME"]         = &Config::getUserName;
            ...
}
template<class R>
R readConfig(std::string customer, std::string settingName)
{
    R returnValue;
    typedef typename std::map<AMD_STD::string,  R (Config::* ) () > ConfigMap_t;
    typedef typename ConfigMap_t::const_iterator ConfigMapIter_t;
    ConfigMap_t configMap = getConfigMap<R>();
    ConfigMapIter_t configIter = configMap.find(settingName);
    if (configIter != configMap.end())
    {
        Config config(customer); // Real instance of Config against which we want to call the function
        boost::function<R ()> configFunction;
        configFunction =
                boost::bind(
                        configIter->second,
                        config);
        returnValue= configFunction();
    }
    return returnValue;
}
template<>
std::map<std::string, bool (Config::* ) ()>  ConfigReader::getConfigMap()
{
    return boolConfigMap;
}
template<>
std::map<std::string, int (Config::* ) ()>  ConfigReader::getConfigMap()
{
    return integerConfigMap;
}
template<>
std::map<std::string, string (Config::* ) ()>  ConfigReader::getConfigMap()
{
    return stringConfigMap;
}

更新它确实通过在地图中使用函数引用而不是 boost::function 来工作

不能将成员函数指针用作普通函数指针,除非成员函数static。应改为将 Boost 绑定与特定对象实例一起使用:

boolConfigMap["USE_NEW_VERSION"] = boost::bind(&Config::useNewVersion, someInstanceOfConfig);
(非静态)成员函数指针

与普通函数指针(或静态成员函数指针)不同的原因是成员函数具有隐藏的"zeroeth"参数,即成员函数内的this指针。

此外,您对boost::function对象的声明应该只是例如

boost::function<bool()>

这将处理返回bool并且不带参数的所有类型的函数。


如果您的编译器足够新,您可能还希望更改为使用 std::functionstd::bind


编辑后使用成员函数指针显示:您还必须正确调用函数指针,例如

(config.*configIter->second)();