|
Boost : |
From: Victor A. Wagner, Jr. (vawjr_at_[hidden])
Date: 2002-08-21 19:14:01
At Wednesday 2002/08/21 15:23, you wrote:
>Hi All,
>
>a discussion on an STLport forum triggered a little discussion on
>lexical_cast. I believe that current implementation has a couple of flaws:
>
>1) it requires that both the Target and Source type have a operator>> and
>operator<<, respectively. There are situation in which it is desirable not
>to define those operators (for example, SGI rope does not have the
>operator>>). It's true that you can always provide something that you don't
>have...
>
>2) sometimes, operator<< or operator>> may perform a task different than the
>one suitable by lexical_cast. For example, suppose you have class vector3d
>whose operator<< produce output in the format "(x, y, z)" (notice the two
>spaces!). It's reasonable (at least, it's reasonable to me) that the
>expression
>
>boost::lexical_cast<std::string>(vector3d(0, 0, 0));
>
>should return the string "(0, 0, 0)", however an exception will be thrown
>because operator<<(istream&, string&) stops at the first space.
I agree here. I've often thought that boost::lexical_cast<std::string>()
should be a special case that doesn't to the >> afterwards, just swap the
buffer (might as well go for speed while we're at it).
>Notice that in both cases, the "problematic" type is the Target. In fact you
>could solve the problem via overload if it was the Source type, but you
>can't overload according to the return type. In order to solve both issues
>and also gain a bit or flexibility the simplest solution would to use two
>helper functions, like this:
>
>template<typename Source>
>inline bool lexical_cast_inserter(std::ostream& interpreter, const Source&
>s)
>{
> return (interpreter << s).good();
>}
>
>template<typename Target>
>inline bool lexical_cast_extractor(std::stringstream& interpreter, Target&
>t)
>{
> return (interpreter >> t).good() && (interpreter >> std::ws).eof();
>}
>
>Target operator()(Source arg) const
>{
> std::stringstream interpreter;
>
> Target result;
> if(!lexical_cast_inserter(interpreter, s) ||
>!lexical_cast_extractor(interpreter, result))
> throw bad_lexical_cast();
> return result;
>}
>
>The reason why the first argument in lexical_cast_extractor is
>std::stringstream and not std::istream is just to allow possible
>optimizations (see below). Then we could write (or let the user write)
>specializations for string and rope like this:
>
>template<>
>inline bool lexical_cast_extractor(std::stringstream& interpreter,
>std::string& t)
>{
> t = interpreter.str();
> return true;
>}
>
>template<>
>inline bool lexical_cast_extractor(std::stringstream& interpreter,
>std::crope& t)
>{
> t = interpreter.str().c_str();
> return true;
>}
>
>Does this make sense to anyone?
>
>Alberto Barbati
>
>_______________________________________________
>Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Victor A. Wagner Jr. http://rudbek.com
PGP RSA fingerprint = 4D20 EBF6 0101 B069 3817 8DBF C846 E47A
PGP D-H fingerprint = 98BC 65E3 1A19 43EC 3908 65B9 F755 E6F4 63BB 9D93
The five most dangerous words in the English language:
"There oughta be a law"
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk