Header
boost/lexical_cast.hppint
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 perceived complexity and high entry level requires an extreme degree of
involvement for simple conversions, and excludes all but a few programmers.
The lexical_cast function template 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
.
For a good discussion of the options and issues involved in string-based
formatting, including comparison of stringstream, lexical_cast,
and others, see Herb Sutter's article,
The String Formatters of Manor Farm
.
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);
}
}
...
}
The following example uses numeric data in a string expression:
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":
namespace boost
{
class bad_lexical_cast;
template<typename Target, typename Source>
Target lexical_cast(Source arg);
}
Unit test defined in "lexical_cast_test.cpp".
lexical_castReturns 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. Note that spaces are significant
in any conversion and are not skipped. If the conversion is unsuccessful, a
bad_lexical_cast
exception is thrown.
The requirements on the argument and result types are:
Source is OutputStreamable, meaning that an operator<<
is defined that takes a std::ostream or std::wostream 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 or std::wistream 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.4].
char unless
the either the Source or the Target type is wchar_t
or a wide-character string type either wchar_t * or std::wstring
in which case wchar_t is used.
Where a higher degree of control is required over conversions, std::stringstream
and std::wstringstream offer a more appropriate path. Where non-stream-based conversions are
required, lexical_cast
is the wrong tool for the job, and is not special-cased for such scenarios.
bad_lexical_cast
class bad_lexical_cast : public std::bad_cast
{
public:
... // same member function interface as std::exception
};
Exception used to indicate runtime lexical_cast
failure.