I am making an attempt in creating dynamic Python-like dicts in C++. One possible approach to implementation (which has its drawbacks, for sure) is
#include <iostream>
#include <variant>
#include <map>
using namespace std;
class dict;
using Atom = variant<bool, int, double, string, dict>;
class dict {
map<string, Atom> data_;
public:
template<typename T>
bool put(const string& k, T&& v) {
data_[k] = std::forward<T&&>(v);
return true;
}
template<typename T>
T& get(const string& k) {
return std::get<T>(data_[k]);
}
template<class T>
bool contains(T&& k) {
return data_.find(std::forward<T&&>(k)) != data_.end();
}
dict(initializer_list<pair<string, Atom>> kvs) {
for (auto kv : kvs) (this->put(kv.first, kv.second));
}
};
Now consider this last variadic initializer. The thing is, it is not exactly as flexible as I would want it to be:
int main() {
// This works:
auto u = dict{
{"a", 9},
{"b", 1.2},
{"c", true},
{"d", dict{
{"e", "f"}
}}
};
// This does not:
auto v = dict{
{"a", 9},
{"b", 1.2},
{"c", true},
{"d", {
{"e", "f"}
}}
};
return 0;
}
The question is, how does one rewrite this so that the necessary initializer lists would be automatically cast to pair<string, Atom>
?
Thanks to @Jarod42, I have managed to come up with this: