我正在实现一个通用设置阅读器。这个想法是我有一个应用程序,它的设置可以是布尔值、整数和字符串。然后我有一个 Config 类,其中实现了此类设置的 getter,config 类在构造函数中获取一个客户,以便它知道它将读取该客户的设置。
我在工作时遇到了麻烦,我认为我在滥用 boost::function 将它与普通函数指针混淆。
在地图中,我希望有引用,而boost::function
应该只在配置读取时绑定,因为我已经Config
为给定的客户分配了一个实例。
问题是我不能使用没有 typedef 的函数指针,这会使模板工作复杂化,有什么更明智的解决方案吗?
#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 来工作