To store simple primitive types such as int
,
long
, double
, and so forth, an
additional type parameter for the container class
templates is needed. For example, to store an int
in a db_vector
, use this container class:
db_vector<int, ElementHolder<int> >;
To map integers to doubles, use this:
db_map<int, double, ElementHolder<double> >;
To store a char*
string with long
keys,
use this:
db_map<long, char*, ElementHolder<char*> >;
Use this for const char*
strings:
db_map<long, const char*, ElementHolder<const char*> >;
To map one const string to another, use this type:
db_map<const char*, const char*, ElementHolder<const char*> >;
The StlAdvancedFeaturesExample::primitive()
method demonstrates more of these examples.
For char*
and wchar_t*
strings,
_DB_STL_StoreElement()
must be called
following partial or total modifications before iterator movement,
container::operator[]
or
iterator::operator*/->
calls. Without the
_DB_STL_StoreElement()
call, the modified
change will be lost. If storing an new value like this:
*iterator = new_char_star_string;
the call to _DB_STL_StoreElement()
is not needed.
Note that passing a NULL pointer to a container of
char*
type or passing a
std::string
with no contents at all will insert
an empty string of zero length into the database.
The string returned from a container will not live beyond the next
iterator movement call, container::operator[]
or
iterator::operator*/->
call.
A db_map::value_type::second_type or
db_map::datatype_wrap should be used
to hold a reference to a container::operator[]
return value. Then the reference should be used for repeated
references to that value. The *iterator is of type
ElementHolder<char *>
, which can be automatically converted to a
char *
pointer using its type conversion operator.
Wherever an auto conversion is done by the compiler, the conversion
operator of ElementHolder<T>
is called. This
avoids almost all explicit conversions, except for two use cases:
The *iterator is used as a "..." parameter like this:
printf("this is the special case %s", *iterator);
This compiles but causes errors. Instead, an explicit cast should be used:
printf("this is the special case %s", (char *)*iterator);
For some old compilers, such as gcc3.4.6, the *iterator cannot be
used with the ternary ?
operator, like
this:
expr ? *iterator : var
Even when var is the same
type as the iterator's value_type
, the
compiler fails to perform an auto conversion.
When using std::string
or
std::wstring
as the data type for dbstl
containers — that is, db_vector<string>
,
and db_map<string, wstring>
— the
string's content rather than the string object itself is stored in order
to maintain persistence.
You can find example code demonstrating string storage in the
StlAdvancedFeaturesExample::char_star_string_storage()
and
StlAdvancedFeaturesExample::storing_std_strings()
methods.