Problem:
Using std::basic_string the extensible way
I'm writing a class that contains a string. But I decided to make it
more extensible and turn it into a class template:
template<typename CharT>
class My
{
std::basic_string<CharT> text;
};
How do I operate on such a string, so that it will work for any valid
instantiation of basic_string? For example, I'd like to append some text
to the end of the string or check if the first letter is lowercase.
Currently I'm doing:
text += "some other text";
For wstring I should probably do:
test += L"some other text";
How do I do it in a generic way?
Solution:
That depends on the meaning of these literals.
Are these only some selected literals of the
corresponding character type with a special
meaning? If so, than a character-depending
policy/traits class would be reasonable, which
would be explicitely specialized for the corresponding
value, e.g.
template <typename CharT>
class MyTraits;
template <>
struct MyTraits<char> {
static const char* append() {
return "some other text";
}
};
template <>
struct MyTraits<wchar_t> {
static const wchar_t* append() {
return L"some other text";
}
};
template<typename CharT>
class My
{
std::basic_string<CharT> text;
typedef MyTraits<CharT> Traits;
void foo() {
text += Traits::append();
}
};
Otherwise you could only declare the member
functions in the My class template and explicitely
specialize them for the corresponding character
type:
template<typename CharT>
class My
{
std::basic_string<CharT> text;
public:
void foo(); // Only declared, not defined
};
template<>
void My<char>::foo() {
text += "some other text";
}
template<>
void My<wchar_t>::foo() {
text += L"some other text";
}
In both cases some preprocessor magic
can help reducing the redundancies.
----------------------------------------------------------------------------
How about writing a helper function to convert a narrow string literal
to an arbitrary basic_string<T>:
// A template to 'widen' a string literal
template < class CharT >
std::basic_string<CharT> widen( char const* str ) {
std::basic_stringstream< CharT > s;
s << str; return s.str();
}
Then you can do
test += widen<char>( "foo bar" );
or
test += widen<wchar_t>( "foo bar" );
as appropriate.
You could even make it a constructor, but it's probably best to make it
explicit in the code when you want this widening.
Using std::basic_string the extensible way
I'm writing a class that contains a string. But I decided to make it
more extensible and turn it into a class template:
template<typename CharT>
class My
{
std::basic_string<CharT> text;
};
How do I operate on such a string, so that it will work for any valid
instantiation of basic_string? For example, I'd like to append some text
to the end of the string or check if the first letter is lowercase.
Currently I'm doing:
text += "some other text";
For wstring I should probably do:
test += L"some other text";
How do I do it in a generic way?
Solution:
That depends on the meaning of these literals.
Are these only some selected literals of the
corresponding character type with a special
meaning? If so, than a character-depending
policy/traits class would be reasonable, which
would be explicitely specialized for the corresponding
value, e.g.
























Otherwise you could only declare the member
functions in the My class template and explicitely
specialize them for the corresponding character
type:
















In both cases some preprocessor magic
can help reducing the redundancies.
----------------------------------------------------------------------------
How about writing a helper function to convert a narrow string literal
to an arbitrary basic_string<T>:
// A template to 'widen' a string literal










as appropriate.
You could even make it a constructor, but it's probably best to make it
explicit in the code when you want this widening.