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

我在工作时遇到麻烦,我认为我正在滥用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 ::函数来工作

有帮助吗?

解决方案

您不能将成员函数指针用作正常函数指针,除非成员函数为 static. 。您应该使用 增强结合 具有特定对象实例:

boolConfigMap["USE_NEW_VERSION"] = boost::bind(&Config::useNewVersion, someInstanceOfConfig);

(非静态)成员函数指针与正常函数指针(或静态成员函数指针)不同的原因是,成员函数具有隐藏的“零”参数,那就是 this 成员功能内部的指针。

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

boost::function<bool()>

这将处理所有类型的函数返回 bool 也没有提出争论。


如果您的编译器足够新,您也可能想更改以使用 std::functionstd::bind.


编辑以显示成员函数指针后:您也必须正确调用功能指针,例如

(config.*configIter->second)();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top