Typesafe operator[] for map<string, variant>
-
Hi all,
I'm currently working on a simple config data storage (typesafe), but I've some problems to implement the accessors.
class ConfigData { using dataTypes = variant<bool, uint8_t, uint16_t, string>; public: ConfigData(string _name, const map<string, dataTypes>_data); uint8_t& operator[](const string& _key) { return std::get<uint8_t>(Data[_key]); } template<typename T> T operator[](const string& _key) const { return std::get<T>(Data[_key]); } private: map<string, dataTypes> Data; }; ConfigData config( "test", { {"foo", "bar"}, {"myInt", (uint8_t)2} } );
What is currently working (but in some sort uggly):
uint8_t a = config.operator[]<uint8_t>("myInt"); config.operator[]<uint8_t>("myInt") = 5; uint8_t b = config.operator[]<uint8_t>("myInt");
What I want to acheave:
uint8_t a = config["myInt"]; config["myInt"] = 5; uint8_t b = config["myInt"];
What is known:
- The number of config elements is known at compile time and not changed
- All types are known at compile time
- No type changes at runtime
- only one type per config-element
Can someone help me, or show the direction?
Best regards
P51D
-
You do speak German, do you not? At least your posting history says so.
Anyways: This is not possible. The fact that you want to return an
uint8_t
from your map must come from somewhere. But the other side of your assignments cannot be used to deduce the template parameters for your calls. The reverse is true: You must somehow provide those types, so that the compiler can check if your assignments are valid after calling your getters.Depending on the context, you can build something decent looking by using
std::visit
, but you probably already know that, and it does not really help you in this particular case.