Sorry, I forgot to mention that since the types can be deduced, you don't have to specify the type:
double d;
std::string s="3.1415";
bool b=boost::lexical_cast(s, &d);
Bjorn
-----Original Message-----
From: Björn Karlsson
Sent: den 25 januari 2002 12:18
To: 'Boost'
Subject: [boost] Proposal for lexical_cast/lexical_convert
The reasoning below is the background for the proposal of adding a nothrowing relative to lexical_cast, called lexical_convert.
There are two main reasons why lexical_cast isn't always a perfect fit (as I see it):
0) In code that doesn't otherwise use exceptions, the error handling can become awkward/messy/inconsistent when using lexical_cast.
1) When a failed conversion is not considered an error, the exception handling stands in the way of code clarity.
I seem to recall an earlier proposal for a lexical_cast, something like
"template<typename Target, typename Source> bool lexical_cast(Source arg, Target* result)", but obviously, that doesn't look like a cast anymore.
It's still useful though, so why don't we give it another name?
I think lexical_convert states the meaning quite clearly:
template<typename Target, typename Source> bool lexical_convert(Source arg, Target* result)
The implementation would be "borrowed" from lexical_cast:
template<typename Target, typename Source>
bool lexical_convert(Source arg, Target* result)
{
# ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
std::strstream interpreter; // for out-of-the-box g++ 2.95.2
# else
std::stringstream interpreter;
# endif
if(!result || !(interpreter << arg) || !(interpreter >> *result) ||
!(interpreter >> std::ws).eof())
return false;
return true;
}
Passing the target by pointer or reference is a tough call - the intention is made clear by using a pointer, but that allows for code like: int* p; boost::lexical_convert<int>(s, p);. On the other hand, passing by reference solves the problem but makes the code less clear. I hesitate to claim that one version is better than the other, so I'll leave it at that and a test for !result (in the end, I think this one boils down to personal preference).
There's not much code, so duplication probably doesn't matter, but the throwing lexical_cast could obviously be implemented in terms of lexical_convert:
template <typename Target, typename Source> Target lexical_cast(Source arg)
{
Target result;
if (!lexical_convert<Target>(arg, &result))
throw bad_lexical_cast();
return result;
}
Sample client code:
void lexical_cast_example(const std::string& s) {
int i=0;
if (boost::lexical_convert<int>(s, &i)) {
std::cout << i << "\n";
}
else {
std::cout << "bad lexical conversion: source type value could not be interpreted as target";
}
try {
i=boost::lexical_cast<int>(s);
std::cout << i << "\n";
}
catch(boost::bad_lexical_cast& e) {
std::cout << e.what();
}
}
The point of the example (for the case where a failed conversion is not considered an error) is that the else could simply be omitted, and that (in this case) there's no reason to throw if noone wants to catch :-).
An open issue would be where the stuff should go - lexical_cast.hpp is very specific, but maybe the right place anyway?
Bjorn
Info: http://www.boost.org Send unsubscribe requests to: <mailto:boost-unsubscribe@yahoogroups.com>
Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.