[lexical_cast] efficiency

'A while back', in the "error_code debate" I used a lexical_cast<> example for demonstrating certain concerns/aspects but the whole post was so long (as usual :) that it was probably read by less than 0.1% of people :) Anyways I'm extracting and reposting this bit now as I think it warrants attention. The first problem is the ('standard') "std::streams vs efficency" issue: - on msvc 9.0 sp1 the single line boost::lexical_cast<int>( "321" ); caused 14 calls to new and 26 calls to EnterCriticalSection() (not to mention vtable initializations, virtual function calls, usage of locales...) the first time it is called, and 3 calls to new and 15 calls to EnterCriticalSection() on subsequent calls...It also caused the binary (which does not otherwise use streams) to increase by 50 kB! ...which is IMNHO abhorrent... (with my usual 'put things in perspective' examples http://www.theprodukkt.com/kkrieger http://www.youtube.com/watch?v=3vzcMdkvPPg :) As a start maybe this problem could be sufficiently "lessened" by providing lexical_cast specializations/overloads that use C library functions (strtol, itoa and the likes) as they suffer less from bloat/performance issues than std::streams. Ideally, IMHO, lexical_cast<> should provide the power/configurability of boost::numeric_cast (so that one can, for example, say I do not need/want to use locales/assume ASCII strings and things like that). The second problem is the use of exceptions (or better of only using exceptions): if, for example, one uses lexical_cast<> deep in the bowels of some parser it is probably "natural" to use a bad_cast exception to report an error to the outside world but if one uses lexical_cast<> to convert a string entered into a widget by a user into an int it would mostly be simpler to have a simple error code if the user entered an invalid string and issue a warning and retry "at the face of the place" (without the need for try-catch blocks)... In other words maybe a dual/hybrid approach of using both exceptions and error codes (through different overloads would be justified). -- "That men do not learn very much from the lessons of history is the most important of all the lessons of history." Aldous Huxley

On Mon, Jan 18, 2010 at 1:30 AM, Domagoj Saric <dsaritz@gmail.com> wrote:
'A while back', in the "error_code debate" I used a lexical_cast<> example for demonstrating certain concerns/aspects but the whole post was so long (as usual :) that it was probably read by less than 0.1% of people :) Anyways I'm extracting and reposting this bit now as I think it warrants attention.
The first problem is the ('standard') "std::streams vs efficency" issue: - on msvc 9.0 sp1 the single line boost::lexical_cast<int>( "321" ); caused 14 calls to new and 26 calls to EnterCriticalSection() (not to mention vtable initializations, virtual function calls, usage of locales...) the first time it is called, and 3 calls to new and 15 calls to EnterCriticalSection() on subsequent calls...It also caused the binary (which does not otherwise use streams) to increase by 50 kB! ...which is IMNHO abhorrent... (with my usual 'put things in perspective' examples http://www.theprodukkt.com/kkrieger http://www.youtube.com/watch?v=3vzcMdkvPPg :)
As a start maybe this problem could be sufficiently "lessened" by providing lexical_cast specializations/overloads that use C library functions (strtol, itoa and the likes) as they suffer less from bloat/performance issues than std::streams. Ideally, IMHO, lexical_cast<> should provide the power/configurability of boost::numeric_cast (so that one can, for example, say I do not need/want to use locales/assume ASCII strings and things like that).
The second problem is the use of exceptions (or better of only using exceptions): if, for example, one uses lexical_cast<> deep in the bowels of some parser it is probably "natural" to use a bad_cast exception to report an error to the outside world but if one uses lexical_cast<> to convert a string entered into a widget by a user into an int it would mostly be simpler to have a simple error code if the user entered an invalid string and issue a warning and retry "at the face of the place" (without the need for try-catch blocks)... In other words maybe a dual/hybrid approach of using both exceptions and error codes (through different overloads would be justified).
Boost.Lexical_cast is *slow* for sure. I have been making my own overloads for my own projects that have it use Boost.Spirit2.1 behind it instead of the stream, and with Boost.Spirit2 in the trunk (2.2, 2.3?) to be released in Boost 1.43 most likely, it has an ability to build parsers based on return types, that would allow us to have a rather very generic lexical_cast that would be a *GREAT* great deal faster. Even for you example of boost::lexical_cast<int>( "321" ), spirit2 could still parse that faster then the native fast C function atoi. Although you can still do that pretty easily with Spirit2 in the trunk like this (not sure if this code has the proper identifier spelling, but close enough, it works like this): int result; std::string input = "321"; boost::spirit::qi::gen_parse(input.begin(), input.end(), result); assert(result==321); And yes, as stated, that will execute faster then the native c functions atoi/strtol/etc... Spirit includes a benchmark that you can run yourself as proof. Plus with spirit, you can customize your grammar inline to, like: tuple<int,double> result; std::string input = "[ 42, 3.14 ]"; boost::spirit::qi::phrase_parse(input.begin(), input.end(), '['>>int_>>','>>double_>>']', result, blank); assert(result==make_tuple(42,3.14)); Or even other more complicated things like: tuple<int,std::vector<double> > result; std::string input = "( 42, [3.14,1.2, 3.4] )"; boost::spirit::qi::phrase_parse(input.begin(), input.end(), '('>>int_>>','>>'['>>double_%','>>']'>>')', result, blank); // assert(result==make_tuple(42,std::vector<double>(3.14,1.2,3.4))); // line of pseudo-code Or the above using the generator parser: tuple<int,std::vector<double> > result; std::string input = "42,3.14,1.2,3.4"; boost::spirit::qi::gen_phrase_parse(input.begin(), input.end(), result, lit(',')); // assert(result==make_tuple(42,std::vector<double>(3.14,1.2,3.4))); // line of pseudo-code So if you want speed, use something else, like Boost.Spirit, Boost.Lexical_cast is made for simplicity, not speed, although much of it could certainly be sped up if Boost.Spirit become part of its back-end, and with some template magic it can even fall back to stringstream if spirit does not know how to parse it directly (thus you would need to supply a grammar).

OvermindDL1 wrote:
On Mon, Jan 18, 2010 at 1:30 AM, Domagoj Saric <dsaritz@gmail.com> wrote:
'A while back', in the "error_code debate" I used a lexical_cast<> example for demonstrating certain concerns/aspects but the whole post was so long (as usual :) that it was probably read by less than 0.1% of people :) Anyways I'm extracting and reposting this bit now as I think it warrants attention.
The first problem is the ('standard') "std::streams vs efficency" issue: - on msvc 9.0 sp1 the single line boost::lexical_cast<int>( "321" ); caused 14 calls to new and 26 calls to EnterCriticalSection() (not to mention vtable initializations, virtual function calls, usage of locales...) the first time it is called, and 3 calls to new and 15 calls to EnterCriticalSection() on subsequent calls...It also caused the binary (which does not otherwise use streams) to increase by 50 kB! ...which is IMNHO abhorrent... (with my usual 'put things in perspective' examples http://www.theprodukkt.com/kkrieger http://www.youtube.com/watch?v=3vzcMdkvPPg :)
As a start maybe this problem could be sufficiently "lessened" by providing lexical_cast specializations/overloads that use C library functions (strtol, itoa and the likes) as they suffer less from bloat/performance issues than std::streams. Ideally, IMHO, lexical_cast<> should provide the power/configurability of boost::numeric_cast (so that one can, for example, say I do not need/want to use locales/assume ASCII strings and things like that).
The second problem is the use of exceptions (or better of only using exceptions): if, for example, one uses lexical_cast<> deep in the bowels of some parser it is probably "natural" to use a bad_cast exception to report an error to the outside world but if one uses lexical_cast<> to convert a string entered into a widget by a user into an int it would mostly be simpler to have a simple error code if the user entered an invalid string and issue a warning and retry "at the face of the place" (without the need for try-catch blocks)... In other words maybe a dual/hybrid approach of using both exceptions and error codes (through different overloads would be justified).
Boost.Lexical_cast is *slow* for sure.
By the way, Maciej Sobczak published alternative implementation of streams together with comparison of performance against boost::lexical_cast http://www.msobczak.com/prog/fastreams/ Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

"Mateusz Loskot" <mateusz@loskot.net> wrote in message news:4B54D635.5080702@loskot.net...
By the way, Maciej Sobczak published alternative implementation of streams together with comparison of performance against boost::lexical_cast
Now if only this would become (or become used in) Boost.IOStreams :) -- "That men do not learn very much from the lessons of history is the most important of all the lessons of history." Aldous Huxley

"OvermindDL1" <overminddl1@gmail.com> wrote in message news:3f49a9f41001180312s74592ff6hb68f3ea13541ddb9@mail.gmail.com...
...Although you can still do that pretty easily with Spirit2...
Wow...cool :) thanks for the examples ;)
Boost.Lexical_cast is made for simplicity, not speed, although much of it could certainly be sped up if Boost.Spirit become part of its back-end, and with some template magic it can even fall back to stringstream if spirit does not know how to parse it directly (thus you would need to supply a grammar).
My thoughts exactly (no need to 'break-change' the interface...only change the implementation)... -- "That men do not learn very much from the lessons of history is the most important of all the lessons of history." Aldous Huxley

18.01.10, 09:30, "Domagoj Saric" <dsaritz@gmail.com>:
The first problem is the ('standard') "std::streams vs efficency" issue: - on msvc 9.0 sp1 the single line boost::lexical_cast( "321" ); caused 14 calls to new and 26 calls to EnterCriticalSection() (not to mention vtable initializations, virtual function calls, usage of locales...) the first time it is called, and 3 calls to new and 15 calls to EnterCriticalSection() on subsequent calls
First of all, which boost version do you use? If it's a recent version, a conversion from char const[4] to int should not create a stringstream object, only the std::locale object. If you alsways use the "C" locale, you can eliminate a construction of that object if you define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE. Can you please run your test it and report a number of calls to the new operator and the EnterCriticalSection function?
...It also caused the binary (which does not otherwise use streams) to increase by 50 kB! ...which is IMNHO abhorrent...
Since std::streams is a part of C++ std library, I'd say it's a problem of a C++ vendor. If you call lexical_cast from more than one DSO, it further increases a size by mutliple instantiations in diferent DSO. I'd personally move some functions to libboostconversion.{so,DLL} to reduce a size but I already hear complaints from header-only lovers ;-)
As a start maybe this problem could be sufficiently "lessened" by providing lexical_cast specializations/overloads that use C library functions (strtol, itoa and the likes) as they suffer less from bloat/performance issues than std::streams.
C and C++ locate are not neccessarily equal.
Ideally, IMHO, lexical_cast<> should provide the power/configurability of boost::numeric_cast (so that one can, for example, say I do not need/want to use locales/assume ASCII strings and things like that).
Flexibility of numeric_cast is a separate project. Check the review schedule.
The second problem is the use of exceptions (or better of only using exceptions): if, for example, one uses lexical_cast<> deep in the bowels of some parser it is probably "natural" to use a bad_cast exception to report an error to the outside world but if one uses lexical_cast<> to convert a string entered into a widget by a user into an int it would mostly be simpler to have a simple error code if the user entered an invalid string and issue a warning and retry "at the face of the place" (without the need for try-catch blocks)... In other words maybe a dual/hybrid approach of using both exceptions and error codes (through different overloads would be justified).
I'm afraid it's too late to change lexical_cast, it's already in the next standard. But there are two libraries in the review queue. I don't know if they give you enough flexibility, though. I hope this helps, Alex

"Alexander Nasonov" <alnsn@yandex.ru> wrote in message news:22191263825453@webmail84.yandex.ru...
First of all, which boost version do you use?
1.40
If it's a recent version, a conversion from char const[4] to int should not create a stringstream object, only the std::locale object.
But it does (create a stringstream object). (the appropriate lcast_streambuf_for_target<int> is not specialized and 'returns' true)
If you alsways use the "C" locale, you can eliminate a construction of that object if you define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE. Can you please run your test it and report a number of calls to the new operator and the EnterCriticalSection function?
From briefly stepping through the lexical_cast<> code again it seems that BOOST_LEXICAL_CAST_ASSUME_C_LOCALE has no influence on the example I gave. It does however make a difference for a reverse cast from int to string and indeed then (in the reverse case) no stream object is created. OTOH the second/reverse case suffers from 'forced std::string usage'...converting an int to a string representation should not require dynamic memory allocation.
Since std::streams is a part of C++ std library, I'd say it's a problem of a C++ vendor.
As much as I dislike 'reinventing the wheel' and generaly bark at all the GUI libraries out there that just "have to" rewrite the standard library along with half of the known universe, I also think that the 'std library' is not some holy cow that should be blindly worshiped. The best example of something wrong with the standard library are precisely std::streams...even the official "Technical Report on C++ Performance" has a special section dedicated to the issue ( http://www.open-std.org/jtc1/sc22/WG21/docs/TR18015.pdf ... section 6 ) that begins with "The Standard IOStreams library (§IS-27) has a well-earned reputation of being inefficient.". Sure, it then goes on to prove that much of this reputation is actually not well earned by offering an example of a ">more efficient<" implementation (than those 'naive' ones) that uses things like dynamic_casts with explicit try-catch blocks ... !? ... it surely does make you want to std::scream ... and wonder just how bad then are those 'naive' implementations... It seems to me that std::screams constitute The Epic Failure of the standard library and look more suited/designed for C# than C++. So much that the Boost coding guidelines should probably warn against using them, in bold and in italics. "To cut the barking"...a particular vendor implementation of iostreams my be particulary horrible (the Dinkumware one certainly does seem so) but iostreams are simply bad by design, flawed in and of themselves. A very basic example: std::stringstream sss; sss << 321; sss.str(); this, among (many many many) other things and to my knowledge of the standard, requires allocation of minimally two buffers (the stream internal buffer and the std::string internal buffer) when it should of course require none as it is ancient knowledge that a base-10 string representation of an int fits in a stack allocated 33 chars large buffer... Sure some implementations will try to alleviate the problem by using "small string optimizations" but that only shifts the problem into more bloated code...
If you call lexical_cast from more than one DSO, it further increases a size by mutliple instantiations in diferent DSO. I'd personally move some functions to libboostconversion.{so,DLL} to reduce a size but I already hear complaints from header-only lovers ;-)
Well, as a small immediate space/bloat-wise improvement you could extract the exception throwing code into a non template function and add a lexical_cast<> specific (instead of the global BOOST_NO_TYPEID) configuration option for turning off RTTI information in bad_lexical_cast...
As a start maybe this problem could be sufficiently "lessened" by providing lexical_cast specializations/overloads that use C library functions (strtol, itoa and the likes) as they suffer less from bloat/performance issues than std::streams.
C and C++ locate are not neccessarily equal.
In what way? wouldn't that imply that one of them is 'wrong'/'incorrect'?
Ideally, IMHO, lexical_cast<> should provide the power/configurability of boost::numeric_cast (so that one can, for example, say I do not need/want to use locales/assume ASCII strings and things like that).
Flexibility of numeric_cast is a separate project. Check the review schedule.
The only related thing I could find here http://www.boost.org/community/review_schedule.html is "String Convert" by Vladimir Batov...were you thinking of that library?
I'm afraid it's too late to change lexical_cast, it's already in the next standard.
Why? As argued earlier 'the standard' should not be some untouchable god-like entity. Besides: - changing boost::lexical_cast<> does not change std::lexical_cast<> (unfortunately :) - replacing the 'screaming' ;) implementation with C functions, Spirit or something else does not necessarily change the interface or the behaviour - adding overloads that accept or return error codes instead of exceptions, or fixed char buffers instead of std::strings also does not change the existing interface...
But there are two libraries in the review queue. I don't know if they give you enough flexibility, though.
Which ones please, I seem to be 'looking without seeing' ;)
I hope this helps, Alex
Any effort is thanks worthy ;) -- "That men do not learn very much from the lessons of history is the most important of all the lessons of history." Aldous Huxley

19.01.10, 21:58, "Domagoj Saric" <dsaritz@gmail.com>:
"Alexander Nasonov" wrote in message news:22191263825453@webmail84.yandex.ru...
If it's a recent version, a conversion from char const[4] to int should not create a stringstream object, only the std::locale object. But it does (create a stringstream object). (the appropriate is not specialized and 'returns' true)
You're right, it's only optimized in the opposite direction, from int to string.
From briefly stepping through the lexical_cast<> code again it seems that BOOST_LEXICAL_CAST_ASSUME_C_LOCALE has no influence on the example I gave. It does however make a difference for a reverse cast from int to string and indeed then (in the reverse case) no stream object is created OTOH the second/reverse case suffers from 'forced std::string usage'...converting an int to a string representation should not require dynamic memory allocation.
At some point in the past, I was considering a conversion to boost::array<char,N>. See http://accu.org/index.php/journals/1375, especially boost::array<char, 3 + std::numeric_limits<int>::digits10> itoa(int n); and char buf[sizeof itoa(n)]; strcpy(buf, itoa(n).elems); Unfortunately, sizeof trick can't be applied to lexical_cast because the target type must be explicit.
Since std::streams is a part of C++ std library, I'd say it's a problem of a C++ vendor.
As much as I dislike 'reinventing the wheel' and generaly bark at all the GUI libraries out there that just "have to" rewrite the standard library along with half of the known universe, I also think that the 'std library' is not some holy cow that should be blindly worshiped. The best example of something wrong with the standard library are precisely std::streams...even the official "Technical Report on C++ Performance" has a special section dedicated to the issue ( http://www.open-std.org/jtc1/sc22/WG21/docs/TR18015.pdf ... section 6 ) that begins with "The Standard IOStreams library (§IS-27) has a well-earned reputation of being inefficient.". Sure, it then goes on to prove that much of this reputation is actually not well earned by offering an example of a ">more efficient<" implementation (than those 'naive' ones) that uses things like dynamic_casts with explicit try-catch blocks ... !? ... it surely does make you want to std::scream ... and wonder just how bad then are those 'naive' implementations...
I fully agree.
It seems to me that std::screams constitute The Epic Failure of the standard library and look more suited/designed for C# than C++. So much that the Boost coding guidelines should probably warn against using them, in bold and in italics.
"To cut the barking"...a particular vendor implementation of iostreams my be particulary horrible (the Dinkumware one certainly does seem so) but iostreams are simply bad by design, flawed in and of themselves. A very basic example:
std::stringstream sss; sss << 321; sss.str();
this, among (many many many) other things and to my knowledge of the standard, requires allocation of minimally two buffers (the stream internal buffer and the std::string internal buffer) when it should of course require none as it is ancient knowledge that a base-10 string representation of an int fits in a stack allocated 33 chars large buffer... Sure some implementations will try to alleviate the problem by using "small string optimizations" but that only shifts the problem into more bloated code...
If you call lexical_cast from more than one DSO, it further increases a size by mutliple instantiations in diferent DSO. I'd personally move some functions to libboostconversion.{so,DLL} to reduce a size but I already hear complaints from header-only lovers ;-)
Well, as a small immediate space/bloat-wise improvement you could extract the exception throwing code into a non template function and add a lexical_cast<> specific (instead of the global BOOST_NO_TYPEID) configuration option for turning off RTTI information in bad_lexical_cast...
I'm aware of this technique. In some cases it turns inline functions uninlined by a compiler to inlined function.
As a start maybe this problem could be sufficiently "lessened" by providing lexical_cast specializations/overloads that use C library functions (strtol, itoa and the likes) as they suffer less from bloat/performance issues than std::streams.
C and C++ locate are not neccessarily equal.
In what way? wouldn't that imply that one of them is 'wrong'/'incorrect'?
One can set two different locales in C++ program with C and C++ interface. You can't use C functions from C++ without saving the old C locale and restoring it after a conversion. Now, if you take into account multi-threading ...
Ideally, IMHO, lexical_cast<> should provide the power/configurability of boost::numeric_cast (so that one can, for example, say I do not need/want to use locales/assume ASCII strings and things like that).
Flexibility of numeric_cast is a separate project. Check the review schedule.
The only related thing I could find here http://www.boost.org/community/review_schedule.html is "String Convert" by Vladimir Batov...were you thinking of that library?
Yes, this one. IIRC, there was a request to review another conversion library but I'm not sure whether it convers lexical conmversions.
I'm afraid it's too late to change lexical_cast, it's already in the next standard.
Why? As argued earlier 'the standard' should not be some untouchable god-like entity.
That's right, but if all votes have already been counted, there is no much you can do.
Besides: - changing boost::lexical_cast<> does not change std::lexical_cast<> (unfortunately :) - replacing the 'screaming' ;) implementation with C functions, Spirit or something else does not necessarily change the interface or the behaviour - adding overloads that accept or return error codes instead of exceptions, or fixed char buffers instead of std::strings also does not change the existing interface...
But there are two libraries in the review queue. I don't know if they give you enough flexibility, though.
Which ones please, I seem to be 'looking without seeing' ;)
I hope this helps, Alex
Any effort is thanks worthy ;)
-- "That men do not learn very much from the lessons of history is the most important of all the lessons of history." Aldous Huxley
-- Alexander Nasonov

----- Original Message ----- From: "Alexander Nasonov" <alnsn@yandex.ru> To: <boost@lists.boost.org> Sent: Wednesday, January 20, 2010 12:41 AM Subject: Re: [boost] [lexical_cast] efficiency
19.01.10, 21:58, "Domagoj Saric" <dsaritz@gmail.com>:
The only related thing I could find here http://www.boost.org/community/review_schedule.html is "String Convert" by Vladimir Batov...were you thinking of that library?
Yes, this one. IIRC, there was a request to review another conversion library but I'm not sure whether it convers lexical conmversions.
Hi, Boost.Convert provides a convert_to function wich the user can specialize. The library doesn't provides string conversions directly. Best, Vicente

"Alexander Nasonov" <alnsn@yandex.ru> wrote in message news:39181263944462@webmail58.yandex.ru...
At some point in the past, I was considering a conversion to boost::array<char,N>. See http://accu.org/index.php/journals/1375, especially boost::array<char, 3 + std::numeric_limits<int>::digits10> itoa(int n);
and char buf[sizeof itoa(n)]; strcpy(buf, itoa(n).elems);
Unfortunately, sizeof trick can't be applied to lexical_cast because the target type must be explicit.
Interesting read :) anyways...there are still a few possible solutions for the explicit target type issue (albeit not of the most beautiful kind ;-) : - a meta-function returning an optimal string representation for a given type e.g. lexical_cast_string<T>::type this would give lexical_cast<lexical_cast_string<unsigned int>::type>( 321 ) which is a 'bit' ugly and redundantly verbose (considering that the source type is specified twice, both explicitly and implicitly)... it can perhaps be enhanced by changing the meta-function into a metafunction class e.g. lexical_cast_string::apply<T>::type now the source type would have to be specified 'twice' only if someone would want to store the result instead of passing it along ( std::puts( lexical_cast<lexical_cast_string>( 321 ) ) ... this could further give a single template parameter version of lexical_cast that uses lexical_cast_string::apply<SourceType>::type for its return type ...).. - as suggested before, overloads accepting externally allocated target/output 'ranges' can be provided (this then also leaves the space for error codes instead of exceptions) - lexical_cast<(t)char (const) *> specializations for built-in types that actually return boost::arrays (that is, in such a case the explicitly specified target type would differ from the actual target type) or (thread-local) static buffers
Well, as a small immediate space/bloat-wise improvement you could extract the exception throwing code into a non template function and add a lexical_cast<> specific (instead of the global BOOST_NO_TYPEID) configuration option for turning off RTTI information in bad_lexical_cast...
I'm aware of this technique. In some cases it turns inline functions uninlined by a compiler to inlined function.
Sure, without moving the implementation into a .cpp file and/or using 'noinline'-like compiler intrisincs some compilers will still inline the code in question but this is not an issue as you simply get the same (binary) code as before...OTOH most compilers will, I suspect, 'properly ignore the inline keyword' (required by a .hpp non-template function) and 'do the right thing'... I've used this technique with MSVC++ many times and it mostly worked as expected... In any case, it is a safe and trivial modification, taking less time than this post ;)
C and C++ locate are not neccessarily equal.
In what way? wouldn't that imply that one of them is 'wrong'/'incorrect'?
One can set two different locales in C++ program with C and C++ interface.
Ah yes... :)
You can't use C functions from C++ without saving the old C locale and restoring it after a conversion. Now, if you take into account multi-threading ...
Maybe multi-threaded CRTs that support per-thread locales can help/be used... In any case the support for the 'use C locale' macro can be extended to work both ways...so that if it is specified the CRT functions are used in the string-to-binary direction also... A 'use no/default/ASCII local' macro would also be welcomed (enabling the use of the most straightforward itoa/atoi-like implementations)
I'm afraid it's too late to change lexical_cast, it's already in the next standard.
Why? As argued earlier 'the standard' should not be some untouchable god-like entity.
That's right, but if all votes have already been counted, there is no much you can do.
I have to repeat my argument(s) ;) : " - changing boost::lexical_cast<> does not change std::lexical_cast<> (unfortunately :) - replacing the 'screaming' ;) implementation with C functions, Spirit or something else does not necessarily change the interface or the behaviour - adding overloads that accept or return error codes instead of exceptions, or fixed char buffers instead of std::strings also does not change the existing interface... " <rant mode> Sometimes it seems to me like there is a tendency to 'cram' as much 'Joe Sixpack' functionality as possible into the standard C++ library with less regard to efficiency and configurability as if to bring the C++ standard library 'up to speed' with the 'competing offers by C# and Java'. IMO this looks like an oxymoronic effort (and in contradiction to the 'you do not pay...' 'prime directive') because no amount of effort will ever 'convert' a 'managed soul'...while OTOH the only ones that have a chance of accepting the 'C++ word', the C programmers, will be further 'repulsed' by such practice that only gives more fuel to Linus Torvalds' irrational anti-C++ rants... </rant mode> I hope that the official std::lexical_cast<> specification does not encourage, or worse imply or mandate, an implementation in terms of std::screams because IMHO even from a design POV it flows natural that std::streams should be implemented using lexical_cast<> functionality (for the appropriate conversions), not vice verse... -- "That men do not learn very much from the lessons of history is the most important of all the lessons of history." Aldous Huxley
participants (5)
-
Alexander Nasonov
-
Domagoj Saric
-
Mateusz Loskot
-
OvermindDL1
-
vicente.botet