The std::basic_string
is tantalizingly general, in that
it is parameterized on the type of the characters which it holds.
In theory, you could whip up a Unicode character class and instantiate
std::basic_string<my_unicode_char>
, or assuming
that integers are wider than characters on your platform, maybe just
declare variables of type std::basic_string<int>
.
That's the theory. Remember however that basic_string has additional
type parameters, which take default arguments based on the character
type (called CharT
here):
template <typename CharT, typename Traits = char_traits<CharT>, typename Alloc = allocator<CharT> > class basic_string { .... };
Now, allocator<CharT>
will probably Do The Right
Thing by default, unless you need to implement your own allocator
for your characters.
But char_traits
takes more work. The char_traits
template is declared but not defined.
That means there is only
template <typename CharT> struct char_traits { static void foo (type1 x, type2 y); ... };
and functions such as char_traits<CharT>::foo() are not actually defined anywhere for the general case. The C++ standard permits this, because writing such a definition to fit all possible CharT's cannot be done.
The C++ standard also requires that char_traits be specialized for
instantiations of char
and wchar_t
, and it
is these template specializations that permit entities like
basic_string<char,char_traits<char>>
to work.
If you want to use character types other than char and wchar_t,
such as unsigned char
and int
, you will
need suitable specializations for them. For a time, in earlier
versions of GCC, there was a mostly-correct implementation that
let programmers be lazy but it broke under many situations, so it
was removed. GCC 3.4 introduced a new implementation that mostly
works and can be specialized even for int
and other
built-in types.
If you want to use your own special character class, then you have a lot of work to do, especially if you with to use i18n features (facets require traits information but don't have a traits argument).
Another example of how to specialize char_traits was given on the
mailing list and at a later date was put into the file
include/ext/pod_char_traits.h
. We agree
that the way it's used with basic_string (scroll down to main())
doesn't look nice, but that's because the
nice-looking first attempt turned out to not
be conforming C++, due to the rule that CharT must be a POD.
(See how tricky this is?)