Quote:But the SC++L algorithms work by way of the iterator mechanism, not the indexing operator -- observe that you can apply algorithms to an std::list, which does not supporting indexing whatsoever. That you can send instances of your SC++L class wrappers to various algorithms has nothing to do with whether or not your operator[] overload works properly/the way you want it to.
Yes I'm fully aware of that, the source above was the minimum I could write up that showed the situation.
The only difference is that instead of having a [] operator as above, my iterators have a dereference operator * that returns the proxy.. the "problem" is still the same however...
Quote:Furthermore, no SC++L container provides this "detect writes via operator[]" behavior. The only one that comes close (and is the odd man out in that respect) is std::map. It is often misunderstood to have "detect writes via operator[]" behavior because you can add new items to the container via someMap[someKeyThatDoesNotYetExist] = someValue;. However, std::map::operator[] is just testing for existence of the key and, if one is not found, creating it. The statement someMap[someKeyThatDoesNotYetExist]; will also add an element, even though no write has taken place.
Yes I know, that's why I need to add support for that behaviour, of course I can throw stl out of the window, but that means I need to rewrite tons of code, using my own interface to containers etc, something that I try to avoid.
Keeping the same interface but adding a behaviour (detecting changes and do something when that happens) is what I want.
I know that the interface wasn't designed to do this, hence the trickery with the Proxy class above.
Quote:I still don't see this as a useful feature. Can you provide a concrete example of some class you've created that would illustrate the utility of this approach? It looks like all you're trying to do is wrap the SC++L containers and provide this "notify on write" feature, which is not as useful as it might sound in general and is likely functionality that should be delegated to an object that can appropriately handle it anyway (unless you're planning to embed some kind of callback that users of the wrapper container can supply, instead of the simple member function you've shown in your examples; this would be slightly more useful, but still fundamentally ugly and overengineered).
Yes, I plan to be able to provide custom "callbacks" (functors), as for usage right now I wan't the following.
* Beeing able to log all changes made to data.
* Mirror containers over a network.
* Mirror containers to an external database.
All of the above can of course be easily done in other ways, I'd just like to use the same interface as SC++L, because it's well known and it's easier to retrofit when needed (only the container constructor and type needs to be changed).
For instance I can currently do the following:
db_map<std::string, Mp3Info> mp3s(dbConnection, "mp3s");mp3s("Test.mp3") = ....;db_map<std::string, Mp3Info>::iterator it = mp3s.find("Cool.mp3");it->second = .....;db_vector<std::pair<int, float> > stuff(dbConnection, "stuff");stuff.push_back(std::make_pair(5, 10.0f));stuff.push_back(std::make_pair(7, 20.0f));stuff.push_back(std::make_pair(3, 30.0f));std::sort(stuff.begin(), stuff.end());stuff.erase(stuff.begin() + 1);stuff.clear();
I currently supports four types of databases (MySql, PostGres, SqlLite and a "no dbase").
The key (if present) and values are serialized into columns in the database.
If the table already existed it's information is "loaded" into the container(upon construction).
I support all methods and operators of the SC++L containers that I've implemented (three so far, but it's easy to do more as needed).
I can use algorithm's on these containers and all changes a propagated to the database, it's rather nifty and I retrofitted a project of mine do store everything in databases very quickly.
Edit: Source tags, added samples and language :)