If you need the power of a database (which can compare externally-meaningful keys, such as strings or integers), the seldom-used ``key'' databases can be a better choice than the ``regular'' databases.
The ``regular'' databases (Database and RefDatabase) copy (with a copy constructor) their key argument on insert, while the ``key'' databases (KeyDatabase and RefKeyDatabase) take over ownership of their key argument.
Creating a cloned copy frees the database from worrying about changes to the original object which might invalidate the comparison order, but can be less efficient if the original object is available to be owned by the database.
There are two situations in which a ``key'' database is a better choice than a ``regular'' database.
Database<String,....> db; String foo; /* build complex key here */ db.ins(foo, ...);
Database will make a copy of foo, and put that into the database, and foo will get destructed when it goes out of scope.
KeyDatabase<String,....> db; String * foo_ptr = new String(); /* build complex key here */ db.ins(foo_ptr, ...);
KeyDatabase will take over ownership of the String pointed to by foo_ptr.
Database<String,....> db; const char * str_ptr = ..... db.ins(str_ptr, ...);
Since ins takes a String & argument for the key object, C++ will make a temporary String object on the stack, which copies over the null-terminated string pointed at by str_ptr. Then, Database will make yet another String object (this one on the heap), and copy again.
KeyDatabase<String,....> db; const char * str_ptr = ..... String * foo_ptr = new String(str_ptr); db.ins(foo_ptr, ...);
This has one visible copy instead of two invisible ones.