
Hi Ivan, I know get/put functions in general serve two orthogonal tasks: (1) access by path, and (2) type conversion. Please note that these tasks are also split in the interface: get_child() does only (1) get_own() does only (2) get() does first (1) and then (2). I expect get() to be by far most often used function from the three (at least in my experience using the library). I don't think that completely redesigning the interface by changing names and moving functions outside class will provide any extra value. The library definitely must provide the above, in this form or another. Member functions or not, it makes little difference. We must also remember that the main goal for the library is simplicity, i.e. we cannot destroy current result of three (readable) lines of code plus 1 include to get appropriately typed value from a config file. By introducing path class and splitting traits I'm going to make these tasks even more obviously independent.
1) value <-> ptree conversion templates
void set( const Value& v, ptree& storage ); void get( Value& v, ptree const& storage ); //throws if conv. fails
These functions could be made more generic by operating only on data stored in ptree. They do not need the whole tree, because they do not use paths.
The default implementation of these functions would use lexical_cast to store/retrieve a value to/from a ptree with only an 'own' value set. The template could of course be specialized for user-defined types.
You can already do that. You have to provide your own inserter/extractor, and specialize it for the types you want. Alternatively, you can provide stream operations for your types (i.e operator << and >>), in this case you do not have to do anything else.
Ambiguous keys
It might be useful in some contexts to make find function throw if there is more than one key with specified name. On the other hand, it would then be quite hard to get a value for any instance of that key. The reverse operation (i.e. find does not throw but I still want to simulate throwing behaviour) is easy. Just do that: if (pt.count(key) > 1) throw ...; I think the deciding point is "if in doubt, do as std containers do". In this case what std::multimap does. Thank you for the time you spent preparing this far reaching proposal. Looking at the practical side of things, you must be aware that implementing that, and getting all corner cases right would require months. How can you be sure that the end result would be significantly better than what we have now? I think you can do everything you want with the current version, the only difference is in syntax. Best regards, Marcin