|
Boost : |
From: Craig Henderson (cdm.henderson_at_[hidden])
Date: 2002-07-22 15:44:45
The lexical_cast<>() function does not respect character traits. I work on a
Win32 platform with MSVC which supports char and wchar_t for 8-bit and
16-bit character representation, respectively. lexical_cast<>() uses a
std::stringstream which is a synonym for template class basic_stringstream,
specialized for elements of type char.
Unfortunately, adding a third (default) template parameter to define the
character type, thus
template<typename Target, typename Source, typename E=char>
Target lexical_cast(Source arg)
{
# ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
std::strstream interpreter; // for out-of-the-box g++ 2.95.2
# else
std::basic_stringstream<E> interpreter;
# endif
}
fails to compile with on both MSVC and g++ 2.95.3-5 on Cygwin as the
templates cannot be deduced. However, I have managed to solve the problem
with the introduction of a second template function, as shown below. The
original function has been renamed lexical_cast_interpreter<>() and has
three template parameters. The new third parameter defines the interpreter
type. The new function actually takes the name of the old one, as it is a
direct replacement. The conditional compilation for g++ is in this function
and typedefs the interpreter that is passed as a template parameter to the
replacement function - a kind of round-about default parameter. Note that
gcc allowed the function to be overloaded with three template parameters,
however, MSVC complains about a 'mismatch in formal parameter list', and
hence the different names. I don't really like 'lexical_cast_interpreter',
does anyone have any better name suggestions?
template<typename Target, typename Source, typename E>
inline Target lexical_cast_interpreter(Source arg)
{
E interpreter;
Target result;
if(!(interpreter << arg) || !(interpreter >> result) ||
!(interpreter >> std::ws).eof())
throw bad_lexical_cast();
return result;
}
template<typename Target, typename Source>
inline Target lexical_cast(Source arg)
{
# ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
typedef std::strstream interpreter; // for out-of-the-box g++ 2.95.2
# else
typedef std::basic_stringstream<char> interpreter;
# endif
return lexical_cast_interpreter<Target, Source, interpreter>(arg);
}
Now I can use this to create a wide-character string
std::basic_string<wchar_t> str = lexical_cast_interpreter<
std::basic_string<wchar_t>, int, std::basic_stringstream<wchar_t> >(123);
Could this amendment be made to the boost header to extend support to
multi-byte characters?
-- Craig
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk