次のような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 ...
すごくいいじゃないですか。
最初のアイデアは、セッターをマップに格納することです。
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_;
もちろん、2 つのマップ ( forint32_t
と for std::string
) を持つことができます。しかし、それはうまくスケーリングしません。float
またはdouble
またはのような引数タイプの新しいセッターを追加user_defined_class
する必要がある場合は、さらにマップが必要になります。
他の方法はboost::any
、この場合、必要なものにreinterpret_cast
戻るboost::function
必要があるため、問題に再び直面することによって使用することです。
質問: 何十億もの if-else ステートメントを書かないように、そのような PropertyManager をどのように管理すればよいでしょうか?