int
represented as a string
, or vice-versa, when
a string
is interpreted as an int
. Such examples
are common when converting between data types internal to a program and
representation external to a program, such as windows and configuration files.
The standard C and C++ libraries offer a number of facilities for performing such conversions. However, they vary with their ease of use, extensibility, and safety.
For instance, there are a number of limitations with the family of standard C
functions typified by atoi
:
sprintf
function, or the loss of portability associated
with non-standard functions such as itoa
.
int
, long
,
and double
.
complex
or rational
.
strtol
have the same basic
limitations, but offer finer control over the conversion process. However, for
the common case such control is often either not required or not used. The
scanf
family of functions offer even greater control, but also
lack safety and ease of use.
The standard C++ library offers stringstream
for the kind of
in-core formatting being discussed. It offers a great deal of control over the
formatting and conversion of I/O to and from arbitrary types through text.
However, for simple conversions direct use of stringstream
can be
either clumsy (with the introduction of extra local variables and the loss of
infix-expression convenience) or obscure (where stringstream
objects are created as temporary objects in an expression). Facets provide a
comprehensive concept and facility for controlling textual representation, but
their relatively high entry level requires an extreme degree of involvement
for simple conversions.
The lexical_cast
template function offers a convenient and consistent
form for supporting common conversions to and from arbitrary types when they are
represented as text. The simplification it offers is in expression-level
convenience for such conversions. For more involved conversions, such as where
precision or formatting need tighter control than is offered by the default
behavior of lexical_cast
, the conventional
stringstream
approach is recommended. Where the conversions are
numeric to numeric, numeric_cast
may offer more reasonable
behavior than lexical_cast
.
The following example uses numeric data in a string expression:int main(int argc, char * argv[]) { using boost::lexical_cast; using boost::bad_lexical_cast; std::vector<short> args; while(*++argv) { try { args.push_back(lexical_cast<short>(*argv)); } catch(bad_lexical_cast &) { args.push_back(0); } } ... }
void log_message(const std::string &); void log_errno(int yoko) { log_message("Error " + boost::lexical_cast<std::string>(yoko) + ": " + strerror(yoko)); }
"boost/lexical_cast.hpp"
:
Test harness defined innamespace boost { class bad_lexical_cast; template<typename Target, typename Source> Target lexical_cast(Source arg); }
"lexical_cast_test.cpp"
.
lexical_cast
Returns the result of streamingtemplate<typename Target, typename Source> Target lexical_cast(Source arg);
arg
into a std::stringstream
and then
out as a Target
object. The conversion is parameterized by the current
lexical_context
, if set. If the conversion is
unsuccessful, a bad_lexical_cast
exception is thrown
if the current lexical_context
is set for throwing or
if there is no current lexical_context
set, otherwise a
Target()
is returned.
The requirements on the argument and result types are:
Source
is OutputStreamable, meaning that an
operator<<
is defined that takes a
std::ostream
object on the left hand side and an instance
of the argument type on the right.
Source
and Target
are CopyConstructible [20.1.3].
Target
is InputStreamable, meaning that an
operator>>
is defined that takes a
std::istream
object on the left hand side and an instance
of the result type on the right.
Target
is DefaultConstructible, meaning that it is
possible to default-initialize an object of that type [8.5, 20.1.3].
Target
is Assignable [23.1].
bad_lexical_cast
Exception used to indicate runtimeclass bad_lexical_cast : public std::bad_cast { public: virtual const char * what() const throw(); };
lexical_cast
failure.
0
and 1
, as valid for bool
; the other tests pass
without problem. The deprecated standard header <strstream>
is used in
preference to the standard <sstream>
header for out-of-the-box g++ support.
std::basic_string
issues need to be catered for.
interpret_cast
that performs a do-something-reasonable conversion between
types. It would, for instance, select between numeric_cast
and lexical_cast
based on std::numeric_limits<>::is_specialized
.