gpt4 book ai didi

c++ - std::map 具有不同参数的成员函数

转载 作者:太空宇宙 更新时间:2023-11-04 11:57:26 25 4
gpt4 key购买 nike

我有一个 DeviceSettingsManager 类,如下所示:

class DeviceSettingsManager
{
int32_t PropertyA();
void SetPropertyA(int32_t prop);
std::string PropertyB();
void SetPropertyB(std::string prop);

// about 50 properties go here ...
}

我需要根据我拥有的属性字符串来设置属性。没有这样的代码:

// Parse property string ("PropertyA = 100, PropertyB = xyz, ...") to key/value pairs

if (key == "PropertyA")
manager.SetPropertyA(value);
else if (key == "PropertyB")
manager.SetPropertyB(value);

// 50 more properties ...

不是很好,对吧?

第一个想法是将 setter 存储在 map 中:

setters_[key](value); // where for example key == "PropertyA" and value = 100

但是有一个问题:我不能在一个映射中存储不同的仿函数:

typedef boost::function<void(int32_t)> setter_int_t;
typedef boost::function<void(std::string)> setter_string_t;
std::map<std::string, ???> setters_;

当然,我可以有两个映射(int32_tstd::string)。但它不能很好地扩展。如果我将被迫添加参数类型为 floatdouble 甚至 user_defined_class 的新 setter,我将需要更多映射。

其他方法是使用 boost::any 在这种情况下我需要 reinterpret_cast 回到 boost::function 我需要,所以再次面对这个问题。

问题:我如何才能以防止编写数十亿个 if-else 语句的方式管理此类 PropertyManager?

最佳答案

最后的做法(不知道是不是最好的):

// checks (map.find(...)) omitted for brevity

struct base_type_holder
{
virtual ~base_type_holder() {};
};

template<typename T>
struct type_holder : base_type_holder
{
typedef T type;
};

std::map<std::string, boost::shared_ptr<base_type_holder> > types_;

template<typename T>
void RegisterSetterType(const std::string& name)
{
types_[name].reset(new type_holder<T>);
}

boost::shared_ptr<base_type_holder> GetSetterType(const std::string& name)
{
return types_[name];
}

template<typename T>
std::map<std::string, boost::function<void(T)> >& SettersMap()
{
static std::map<std::string, boost::function<void(T)> > settersMap;
return settersMap;
}

template<typename T, typename H>
void AddSetter(const std::string& name, void (H::*Setter)(T))
{
static H settingsManager;
RegisterSetterType<T>(name);

SettersMap<T>()[name] = boost::bind(Setter, &settingsManager, ::_1);
}

void CallSetter(const std::string& name, const std::string& value)
{
boost::shared_ptr<base_type_holder> base_type = GetSetterType(name);
if (dynamic_cast<type_holder<int32_t> *>(base_type.get()))
{
SettersMap<int32_t>()[name](atoi(value.c_str()));
}
else if (dynamic_cast<type_holder<std::string> *>(base_type.get()))
{
SettersMap<std::string>()[name](value);
}
}

// Now somewhere in .cpp
AddSetter<int32_t, DeviceSettingsManager>("PropertyA", &DeviceSettingsManager::SetPropertyA);
AddSetter<const std::string&, DeviceSettingsManager>("PropertyB", &DeviceSettingsManager::SetPropertyB);

// other...

// later
CallSetter(key, value); // key = "PropertyA", value = "100"

关于c++ - std::map 具有不同参数的成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15585546/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com