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.