[lexical_cast] A suggestion

I use boost::lexical_cast quite a bit. Possibly due to specifics of my task I constantly stumble upon two things: 1. It throws if/when conversion fails; 2. It requires the 'Target' class to be default-constructible. I'd like to suggest extending the existing template<class Target, class Source> Target lexical_cast(Source const& arg) interface with template<class Target, class Source> Target lexical_cast(Source const& arg, Target const& failure_value) The behavior of the latter would be to return the 'failure_value' if/when the conversion fails. That communicates the fact of the conversion failure differently (without an exception thrown), i.e. its usage would be as following: int value = boost::lexical_cast(some-string, -1); if (value == -1) conversion failed. In fact, my usage pattern is such that I often do not even need to check the success of the conversion -- if the conversion fails, the supplied failure/default value is returned/used and proceeded with. Secondly, the proposed lexical_cast requirements would be looser -- no need for the default-constructibility of the Target, only the copy-constructibility (as already required anyway). For that the current lexical_cast implementation if(interpreter << arg) { Target result; if (interpreter >> result) return result; } throw_exception(bad_lexical_cast(typeid(Source), typeid(Target))); return Target(); // normally never reached (throw_exception) would change (for the proposed interface) to something like if(interpreter << arg) { Target result(failure_value); if (interpreter >> result) return result; } return failure_value; I am not sure how much value such an interface extension might have for others but for my usage pattern the benefit would be quite visible as the majority of our classes are with no default constructors and handling conversion-failure exceptions is quite a hassle... not to mention that for whatever guided/misguided reasons exceptions are virtually banned for our mission-critical development. Best, V.

I would like to add my support for this proposed change: On Tue, Jan 13, 2009 at 12:26 PM, Vladimir Batov <batov@people.net.au>wrote:
I have similar use-cases where I require a non-throwing implementation and hence I have to, reluctantly avoid lexical_cast. This change appears to be very compelling.
Best, V.
Neil Groves

On Tue, Jan 13, 2009 at 7:26 AM, Vladimir Batov <batov@people.net.au> wrote:
This doesn't look like a good interface due to using a casted value as a "null"-code. This code would fail when "-1" is a value of some-string. This could lead to very big problems! I would suggest something more like boost::optional<int> value = boost::lexical_cast(some-string,boost::no_throw); if(!value) conversion failed. Chris

On Tue, Jan 13, 2009 at 3:50 PM, Chris Weed <chrisweed@gmail.com> wrote:
I prefer the original suggestion of providing a failure value for most of my uses because: 1. Often I do not want to check an error, I have a value in mind to use in the case of error 2. It removes the requirment for a default constructor I see that if we need to handle an error condition then the ability to return an optional<Target> is a good plan. Perhaps two new overloads would be optimal? Neil Groves

Well, "very big problems" sounds like a stretch. I've been using a lexical_cast equivalent in that fashion and in practice very often there are values that are well out our sensible range. If, say, -1 is no good then something like INT_MAX might well be. Quite often though I do not even need to look for a ""null"-code" as I provide the *default* value instead. I.e. a value inside the sensible range that I proceed with when the conversion fails. If all that is no good, then I'd expect the existing interface to come to the rescue. In addition, the interface above does not seem to address #2, i.e. the default-constructability requirement of the Target which for my a big hassle. Best, V.

Vladimir Batov <batov <at> people.net.au> writes:
int value = boost::lexical_cast(some-string, -1); if (value == -1) conversion failed.
I know that you know this but lexical_cast was designed to be constistent with {static,const,reinterpret}_cast<Target>(source). It doesn't have to be named lexical_cast. Most likely you're converting from a string, you could name it from_string or something similar. -- Alex

I know that you know this but lexical_cast was designed to be consistent with {static,const,reinterpret}_cast<Target>(source).
Understood. I do not think though that it might be an issue. The similarity is only cosmetic as the group is supported by the language, works with types when lexical_cast is a library solution, works with values. So, in fact, the user has to learn lexical_cast *not* to use it as the "real" type casts. More so, I'd expect lexical_cast interface extended without interrupting whatever impression/behavior the user has established in relation with the current interface.
It doesn't have to be named lexical_cast. Most likely you're converting from a string, you could name it from_string or something similar.
I indeed often (in 70%) use it for string-to-something conversion. However, for the remaining 30% I need it beyond string-to/from conversion. As for "from_string" I certainly had to do something along the lines for myself. However, beyond my private sandbox I am always reluctant introducing a new vocabulary when the existing can be sensibly reused and (IMHO) improved. Best, V.

With no volunteeres coming forward :-) , I am considering extending the lexical_cast interface as described below. Is there any chance of that change integrated? Is there a process to achieve that? I understand it would go through an acceptance review as for new components but it has to go through some kind of review, check. Is there anyone at present supporting/maintaining the component? I understand these might be boring/annoying questions for seasoned boosters. My humble apologies go to them. Any pointers would be immensely appreciated. Best, V. ----- Original Message ----- From: "Vladimir Batov" <batov@people.net.au> Newsgroups: gmane.comp.lib.boost.devel To: "Boost Developers' List" <boost@lists.boost.org> Sent: Tuesday, January 13, 2009 11:26 PM Subject: [lexical_cast] A suggestion

Vladimir Batov <batov <at> people.net.au> writes:
Is there anyone at present supporting/maintaining the component? I'm a maintainer.
If you really want to push this change, you should involve the C++ committee, especially the authors of N1973 Kevlin Henney and Beman Dawes. Thanks, Alex

Alex, Thank you for getting back to me. Much appreciated.
I'm against this change. See my other messages in this thread for details.
Well, I certainly read your messages in the thread and somehow they did not come across as you were against. It's certainly clear now. Even though I was not proposing to change anything. It was clearly an addition, i.e. it would not have any disruptive impact. However, the practical usefulness of that addition is substantial (well, for my and I suspect others usage pattern).
I'm a maintainer.
Thanks for the info.
If you really want to push this change, you should involve the C++ committee, especially the authors of N1973 Kevlin Henney and Beman Dawes.
I am CCing the authors. Maybe they see it in a more favorable light. :-) Not sure through if they get back to me/us on that. Best, V.

Hi,
I haven't been following the discussion, so would it be possible for you to provide some context/background? Thanks, Kevlin -- ____________________________________________________________ Kevlin Henney phone: +44 117 942 2990 mailto:kevlin@curbralan.com mobile: +44 7801 073 508 http://curbralan.com fax: +44 870 052 2289 Curbralan: Consultancy + Training + Development + Review ____________________________________________________________

Kevlin, Thank you for your prompt reply. Much appreciated.
I haven't been following the discussion, so would it be possible for you to provide some context/background?
To see all opinions expressed the discussion could be found at http://groups.google.com/group/boost-developers-archive/browse_thread/thread... The description of my suggestion/request is as follows: boost::lexical_cast is very important to me and I use it quite a bit. Possibly due to specifics of my task I constantly struggle with two things: 1. It throws an exception if/when conversion fails (which is not an exceptional situation); 2. It requires the 'Target' class to be default-constructible (many of my classes do not have). I'd like to suggest extending (no disruption to the existing interface/users) the existing template<class Target, class Source> Target lexical_cast(Source const& arg) interface with template<class Target, class Source> Target lexical_cast(Source const& arg, Target const& default_value) The behavior of the latter would be to return the 'default_value' if/when the conversion fails. That communicates the fact of the conversion failure differently (without an exception thrown) as IMHO a conversion failure is not really that exceptional (rather common). The usage would be something like: int value = boost::lexical_cast(some-string, -1); if (value == -1) conversion failed. In fact, my usage pattern is such that I often do not even check the success of the conversion -- if the conversion fails, the supplied failure/default value is returned/used and proceeded with. Equally importantly, the requirements of the proposed/extended lexical_cast would be looser -- no need for the default-constructability of the Target, only the copy-constructability. That proposed/additional lexical_cast interface would be implemented something like if(interpreter << arg) { Target result(failure_value); if (interpreter >> result) return result; } return failure_value; as opposed to the current lexical_cast implementation: if(interpreter << arg) { Target result; if (interpreter >> result) return result; } throw_exception(bad_lexical_cast(typeid(Source), typeid(Target))); return Target(); // normally never reached (throw_exception) I am not sure how much value such an interface extension might have community-wide (although a few people on the list expressed their support) but for our deployment the benefit would be quite substantial as the majority of our classes are with no default constructors. That's been a serious stumbling block for us adopting lexical_cast as-is (I had to write a replacement). Having to provide the default constructor for such classes is a huge hassle for the developer and wide-open for eventual abuse/confusion. Having to handle bad_lexical_cast exceptions is in all honesty quite a hassle (with my usage pattern) and probably not exactly justified as there is nothing exceptional about failed conversion (more like I could not open a file)... not to mention that for whatever guided/misguided reasons exceptions are virtually banned for our mission-critical development. Thank you for your consideration. Looking forward to hearing from you. Best, V.

On Feb 3, 2009, at 3:35 PM, Vladimir Batov wrote:
Last time this topic came up I took some time to modify lexical_cast.hpp (starting from boost 1.37.0 source) to fit this interface. I also added a specialization for boost::optional<T> that instead of throwing bad_lexical_cast, simply returned an empty optional type (which required rewriting optional_io.hpp, as I believe it has a bug: https://svn.boost.org/trac/boost/ticket/2659 ). Here's some example usage: http://codepad.org/hn6MjKjm modified lexical_cast.hpp: http://codepad.org/JAA4Me9Q modified optional_io.hpp: http://codepad.org/8ablH1Nq I too would love to see these extensions to lexical_cast, but in the meantime I've been using these modified versions. Just thought I'd share them in case anyone else was interested. -- Andrew Troschinetz Applied Research Laboratories

Andrew Troschinetz <ast <at> arlut.utexas.edu> writes:
Here's some example usage: http://codepad.org/hn6MjKjm
It's not clear from the example that this inliner lexical_cast< optional<int> >("x").get_value_or(-1); is a replacement for lexical_cast("x", -1); It's not conceptually correct but we already have an exception for handling spaces in strings. I should think about making one more exception for optional<T>. Though, the inliner is not short, not sure people will like it. -- Alex

On Feb 4, 2009, at 10:53 AM, Alexander Nasonov wrote:
I actually hadn't thought of that inliner, but now that I see it I prefer it because I think it's cleaner conceptually and from an interface standpoint. It also means there's no need for a lexical_cast specialization for optional types, which I wrote all the while with a feeling of "there must be a better way to do this." But that inliner still doesn't get around the problem of types that aren't default constructible. -- Andrew Troschinetz Applied Research Laboratories

... But that inliner still doesn't get around the problem of types that aren't default constructible.
IMHO the default-constractibility requirement is unfortunate and in my particular case is not achievable. Understandably a library can only create an object it knows nothing about by imposing certain conditions (like demanding a certain constructor). Therefore, I'd consider any attempt to avoid that "delicate" situation to be a good design philosophy as it extends the applicability scope. Best, V.

Alexander Nasonov <alnsn <at> yandex.ru> writes:
I can confirm that this is Kevlin's prefered option. See for example this discussion: http://lists.boost.org/Archives/boost/2005/05/86492.php Alex

Alexander Nasonov wrote:
First of all, I think this would be useful addition. Quite often I do need to supply a default value that will be returned if the conversion fails. However, I'd rather opt for not involving optional into this. Not only does it make the expression longer and less clean, it introduces a dependency on another library and makes me wonder how can I lexical_cast optionals. I like the lexical_cast< int >("x", -1); syntax much more. If the syntax is considered unacceptable, I can suggest another alternative: int x = lex_cast< int >("x").with_default(10); int y = lex_cast< int >("y").or_default_constructed(); The trick is that lex_cast returns a proxy that can either be converted to int (in which case it does the regular lexical_cast) or can be used to provide additional tweaks, like the ones above. Obviously, the function name should be different from lexical_cast, as it can be incompatible in some cases.

The situation with the additional default parameter to lexical_cast is just crazy. People clearly need the behavior and have been asking for it since 2005 and they still get nothing but excuses and explanations instead. In fact, according to Kevlin's http://lists.boost.org/Archives/boost/2005/05/85519.php post it was the original behavior. I greatly appreciate Kevlin's contribution but unfortunately in the current form lexical_cast is hardly useful to me (and I suspect many others) -- throwing an exception (and having to process it) on something as mundane as string conversion failure is, well, a bit heavy-handed -- it results in unbelievably messy and ugly code. The second issue (actually *first* for me) is the default-constructability. I can understand Kevlin's reaction like "we looked at the possibilities, we rejected them". Well, maybe it is time to have a look again. We make wrong decisions all the time. There is nothing wrong in revisiting/re-evaluating old decisions as we get more experience. I sympathize with the idealistic desire for lexical_cast to look like the dynamic_cast et al. The problem is that no matter how you make lexical_cast look it does not do what other language-supported casts do -- dynamic_cast el al work with *types*, lexical_cast works with *values*. Making lexical_cast look like what it is not (the "real" casts) has no practical value and is just misleading. Now seemingly out of desperation people are venturing into lexical_cast<optional> lex_cast< int >("x").with_default(10); lex_cast< int >("y").or_default_constructed(); It's just crazy from the usability point of view. Are you sure users will appreciate all that mounting complexity on top of lexical_cast? All that is needed lexical_cast(Source const&, Target const& =Target()) or most likely a completely independent overload lexical_cast(Source const&, Target const&) That overload can live side-by-side with the original lexical_cast without disturbing it... unless "lexical_cast" character sequence has been trade-marked. I'll be first to use it. I need scissors with two rings for fingers. The scissors' designer might strongly insist on a variation with just one ring for one finger due to its minimalist and beautiful design looking like something else. It has no *practical* use for me. We can strike a compromise or I'll have to go someplace else. That's what I understand has been happening since 2005 -- people have been simply turned away and that is wrong -- we write code for people and want people using our code (I do). C++ is full of compromises -- compromises due to C compatibility, usability, just convenience. People love it. Best, V.

On Fri, Feb 6, 2009 at 17:01, Vladimir Batov <batov@people.net.au> wrote:
I have no idea what you mean by dynamic_cast working with "types" not "values". static_cast<float>(1000000000u) drastically changes the representation and the type, just like lexical_cast<float>("1000000000") does. And optional<> is not that strange. The first example in its documentation is "optional return values" ( http://www.boost.org/doc/libs/1_37_0/libs/optional/doc/html/boost_optional/e... ), which is exactly what attempt_lexical_cast<T>(x) just calling lexical_cast<optional<T> >(x) makes perfect sense to me, though it's so trivial that it seems like a waste to provide the extra function. Having the different semantics for the different type is just like dynamic_cast, just this one uses optional instead of *. One very clear use: if (optional<int> oi = lexical_cast<optional<int> >(mystring)) { int i = *oi; ... use i ... } else { ... parse failed ... } And if you want defaults: int i = -1; if (optional<int> oi = lexical_cast<optional<int> >(mystring)) { i = *oi; } ... use i ... Or, using the helper: int i = lexical_cast<optional<int> >(mystring).get_value_or(-1); Why is this so bad?

I have no idea what you mean by dynamic_cast working with "types" not "values".
I am sure to do: Foo& foo = dynamic_cast<Foo&>(moo); Foo& foo = const_cast<Foo&>(moo); same instance, different type.
static_cast<float>(1000000000u) drastically changes the representation and the type,
Yes, for static_cast I'll give you that. However, it is not static_cast *own* quality as it simply piggy-backs on the built-in *language* support for conversions between *related* types. That way, static_cast is nothing more but syntactic sugar as "float foo = 10u" will just do.
just like lexical_cast<float>("1000000000") does.
lexical_cast is different as it's not jusr sugar-coating and "float foo = "10" " wil not take you anywhere. Therefore, if we have to find the closest ?_cast that lexical_cast looks like, then, I'd choose reinterpret_cast -- conversions between *unrelated* types. And I am personally not exactly comfortable with that comparison as I do not see it serving any useful purpose. All in all, these language-supported casts behave *differently* -- the purpose is the paramaunt. It is arguable if their visual similarity is beneficial or a hindrance (the user still need to understand their differences and usage subtleties). Now lexical_cast steps in and seemingly sactifices usefulness/purpose for appearance. Not the right choice is you ask me (you obviously are free to disagree).
And optional<> is not that strange.
To start with "strangeness" is subjective. And that is last of my worries. I thought I voiced my reasons against it -- it still requires the default-constructability. I work with quite complex classes which happen not to have the default constructor. Second, IMHO lexical_cast is seemingly straightforward (easy to grasp for a casual user). Throwing optional<> into the mix does not seem justified (that's surely subjective unlike the default-constructability).
Well, if you want lexical_cast (and Boost) *not* used in the wide, then keep mounting these wonderful complexities and interfaces. Surely the users will be very supportive of your effort. Best, V.

Well, that was somewhat terse and unfriendly. Apologies. I'll elaborate and give you metrics. 1. int i = lexical_cast<optional<int> >(mystring).get_value_or(-1); 2. int i = lexical_cast(mystring, -1); #1 and #2 do exactly the same (although #2 does it better as it does not demand default-constructability). However, #1 has 3 new special-vocabulary elements (lexical_cast, optional, get_value_or) vs. just one entry for #2. I.e the entry level for a user to deploy #1 is at least 3 times higher than #2. You might say -- "no, big deal, I already know all that". You most likely do. Others might not. Application programmers often can qualify only as casual Boost users. And often it's not entirely their fault as they have a lot to know/care about beyond Boost (like their domain-specific stuff). Unfortunately, learning something new for those app. programmers is often secondary (unfortunate but fact) as they are too busy coding their domain-specific stuff. Therefore, learning something new can only be learnt if it passes some mental complexity level and if it fits some mentally allocated time. If learning/diversion spills over complexity/time limits, that new thing is dropped and something is hand-coded the ugly way. I personally want (for selfish reasons) to see those guys engaged and using Boost rather than repelled by interface/deployment complexity. Another thing is that #1 is twice as long (and IMHO ugly :-) ). In isolation it might be OK (the length it is). On a bigger scale you are suggesting I write twice as much code as I have to. With #1 I'll have to spend one hour writing code when with #2 I could spend only half an hour writing code and the remaining half an hour enjoying myself ;-). Then, I'll have twice as much code to proof-read, to debug, to maintain, to test. As it is pretty much what I do all day long, you just robbed me of half my working day (or made me work twice as hard). All that for what? Some abstract idea/ideal of keeping lexical_cast looking similar to static_cast? Best, V.

Scott McMurray wrote:
Like I said: 1. It is longer and more clumsy than lexical_cast< int >(str, 1). It does introduce enough scaffolding that user has to type to avoid lexical_cast altogether in such cases. 2. It introduces dependency on optional. 3. It bans lexical_casting optionals.

Vladimir Batov wrote:
I disagree. Making lexical_cast behave similar to other casts makes perfect sense. It does change the type of its argument just as well as its physical representation.
No, that kind of implementation seems unacceptable to me. I want lexical_cast to throw exceptions just as often as I don't want it to. And, of course, I'm against introducing a breaking change.
or most likely a completely independent overload
lexical_cast(Source const&, Target const&)
That would be my preferred way to implement this extension.

Yes, agreed. That the only IMHO way to implement that "extension" -- without disturbing the existing lexical_cast. I threw the first one in almost accidently. Kevlin argued (in a separate discussion) that lexical_cast<Foo>(string) lexical_cast(string, some_foo) were distant syntactically and I argued that they were not as they could in fact be two "sides" of the same "coin" lexical_cast(Source const&, Target const& =Target()) Then, I brought it to this thread just to confuse things. V.

On Tue, Feb 3, 2009 at 12:41 AM, Vladimir Batov <batov@people.net.au> wrote:
not have any disruptive impact. However, the practical usefulness of that addition is substantial (well, for my and I suspect others usage pattern).
Just to jump in here, I'm one of those "others". I ended up writing a function that try'd the lexical_cast, then on exception, returned the default value that was passed to the function. I used this often in parsing files. It looked something like: template <typename T, typename S> T try_lexical_cast(const S &value, T default_value) { /* stuff */ } It would be really nice if we didn't have to pay for the cost of an exception every time that happens in cases where we are expecting lots of failures but also have an appropriate default value on hand. And, to be clear, I am *for* Vladimir's addition. --Michael Fawcett

on Mon Feb 02 2009, Alexander Nasonov <alnsn-AT-yandex.ru> wrote:
I am too. Vladimir, I believe the functionality you want is badly needed, but it shouldn't be part of lexical_cast. lexical_cast is conceptually simple and should remain that way. The proper interface for the functionality you seek should be considered without reference to lexical_cast. In fact, if we put together all the badly needed functionality that overlaps with lexical_cast, and give it appropriate interfaces, I'm not entirely convinced that there would be much use for lexical_cast anymore. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Really what is with all of the "slippery slope" arguments? People are not asking for the kitchen sink. We just want a nothrow version of the cast and to do that, a default value is needed. I always use my own extension "lexical_cast_nothrow" operator anyway that just catches the exception and returns a supplied default value if necessary. Lots of times there are cases when a default value simply will not be acceptable, but quite often one will. Why can't it be easy to support both models? I had not even heard of the <optional> library until reading this thread. I might update my little boost extension after checking to see how <optional> affects performance and code bloat -- but really, <optional> looks rather more complicated than necessary. I heard once that google was experimented with the number of search results that it returned. If they returned 100 results instead of 10, the search took .4 seconds longer. They found that the extra delay reduced the number of searches by 20% within the experimental group. The moral of the story: some times it is the little conveniences that count. I think that supplying a 'nothrow' version of lexical_cast is one of those little conveniences that would definitely count. --Ben

on Sun Feb 08 2009, Ben Muzal <bmuzal-AT-gmail.com> wrote:
That's not my concern. My concern is that I don't think lexical_cast is a particularly good interface for its main uses, which could be thought of as "to-string" and "from-string."
People are not asking for the kitchen sink. We just want a nothrow version of the cast and to do that, a default value is needed.
I wouldn't say that. boost::optional is another option. In fact, if boost::optional doesn't already provide the exact streaming operator you need, I'd be a little surprised. If it has no streaming operator, we could consider adding the needed one. If it has the wrong streaming operator, it would be pretty easy to invent template nothrow, such that you can write optional<Foo> = lexical_cast<nothrow<Foo> >( something )
I think you can easily avoid that problem.
I just don't think lexical_cast is the interface we need for most convenient string conversions.
It has exactly the right semantics, and it tells you more than the version with the default does. With the default, you can't tell whether there was any valid input there or not, because the value represented in the input could be the same as the default.
No doubt.
I think that supplying a 'nothrow' version of lexical_cast is one of those little conveniences that would definitely count.
Maybe so, but I don't think lexical_cast is all that well-designed for convenience to begin with, and tacking on little convenience features isn't likely to yield a very clean interface. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
I disagree. lexical_cast was designed to be simple to use, and I think it does it very well. The "to-string" and "from-string" conversions, in their simple form, are just corner cases. If I want to simply parse an int, I don't want to make up a Spirit grammar for that or even use scanf. I need a C++-style of strtol, which is safe in terms of buffer allocation and types. This is what lexical_cast tries to achieve and it does, to some degree. I don't know of any other tools that come this close to this goal, neither in Boost, nor outside of it.
I've already expressed myself on this. I just want to add that optional does define its streaming operators, and the way they work is no compatible with the goal we're trying to achieve with this extension.
Do you have a better interface in mind?
The point is, often I don't care if the default was actually read from the string or taken from the argument. And I don't want to care (which would be necessary if optional was used). If I care whether the string was actually read, I use the throwing version of lexical_cast.

on Sun Feb 08 2009, Andrey Semashev <andrey.semashev-AT-gmail.com> wrote:
Eh? What other uses has it got?!
If I want to simply parse an int, I don't want to make up a Spirit grammar for that or even use scanf.
scanf is *way* lighter weight that lexical_cast.
I need a C++-style of strtol, which is safe in terms of buffer allocation and types.
So write that.
So write one (just my opinion). lexical_cast means something very strange and overly-general, and we should write something targeted at the real-world uses people actually have.
Then it's easy enough to define the derived template that *is* compatible... although as I've said before I don't think lexical_cast is the right tool for this job anyway.
It would take some thought and discussion to perfect, but just off the top of my head, I'd want something like this: namespace str { template <class T> struct value { operator T() const; // throws iff parse unsuccessful bool parsed() const; // true iff parse succecssful ... }; template <class String, class T> string::value<T> string::as<T>(String const&); template <class String, class T> typename enable_if<is_integral<T>, string::value<T> >::type string::as<T>(String const&, unsigned base); template <class T> std::string to_str(T const& x); template <class String, class T> String to_str(T const& x); }
Yes, but sometimes you will. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

My reply may be too late for the discussion, but I'll answer anyway... David Abrahams wrote:
To convert objects of different types between each other. I don't know if conversion between types that are not strings is widely used or not. Conversions between custom and fundamental floating point types come to mind as an example.
It may be lighter in terms of implementation and speed, but certainly not in terms of interface clarity and safety. And anyway, lexical_cast can potentially be faster than scanf, if it is optimized the way it was for the "to-string" conversions.
I'm quite happy with lexical_cast, except for this default-value issue. Why would I write something new?
This does look pretty much like lexical_cast, a bit extended for string conversions, though. I'm not against a better support for parsing or formatting in Boost. However, in case of simple needs, I think the potential of lexical_cast is not yet exhausted. Adding another library with so much overlapping functionality may confuse users.

on Mon Feb 09 2009, Andrey Semashev <andrey.semashev-AT-gmail.com> wrote:
Yes, I meant what other real-world uses has it got?
I don't know if conversion between types that are not strings is widely used or not.
Then take it from me, it isn't.
Conversions between custom and fundamental floating point types come to mind as an example.
Yes, hypothetically. In reality, no way. Nobody who wrote a custom floating point type would leave its conversion to double up to the vagaries of iostreams, especially ones that hadn't had the right manipulators applied.
I'm quite happy with lexical_cast, except for this default-value issue. Why would I write something new?
Because where you want it to go clearly doesn't mesh with the vision of the original author or the maintainer.
Maybe, but lexical_cast clearly isn't targeted at what some large segment of users needs. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
lexical_cast was at best an experiment. In some limited contexts a generic from_string and a generic to_string might make sense. But a generic from/to anything, using a string as intermediate representation, is something done just because it can be done, not because it is useful or meaningfully specified. I quacke at the idea that it is being used in a mission-critical project.
There isn't really much use anyway. It gives no control over the format or, for that matters, over anything. -- Genny

on Sun Feb 08 2009, Gennaro Prota <gennaro.prota-AT-yahoo.com> wrote:
Yes, that's what I've been saying. I don't particularly like the idea of lexical_cast, and trying to stretch it to cover cases it wasn't designed for will just put more important functionality in that bucket.
I quacke at the idea that it is being used in a mission-critical project.
IMO that's an overreaction, but anyway...
...I think you're just making my point for me. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
participants (14)
-
Alexander Nasonov
-
Andrew Troschinetz
-
Andrey Semashev
-
Ben Muzal
-
Chris Weed
-
David Abrahams
-
Deane Yang
-
Gennaro Prota
-
Kevlin Henney
-
Michael Fawcett
-
Neil Groves
-
Scott McMurray
-
Sebastian Redl
-
Vladimir Batov