
This is a spin off from the thread "[lexical_cast] A suggestion" While trying to get lexical_cast and optional to play nice I've run up against some problems with the InputStreamable solution for optional types in optional_io.hpp. The crux of the problem is that I think any given optional type should behave as much like the type it wraps as possible. For example I think this: stringstream sin ("1.2.3.4.5"); optional<double> token; while (sin >> token) cout << token << endl; Should have the same output as this: stringstream sin ("1.2.3.4.5"); double token; while (sin >> token) cout << token << endl; And that this shouldn't fail: stringstream sin ("test"); optional<string> token; sin >> token; // token shouldn't be empty The current InputStreamable solution for optional does not pass these tests. But that's not all, I also believe that there is room for even more improvement here! Since it's semantically valid to have an un- initialized optional type, I think failure to extract something off a stream should return an empty optional type _without_ setting the failbit on the stream. Here's a usage example that demonstrates what I mean by that: // output is "1 nan nan nan nan 5.5 nan nan nan nan nan nan nan -3.2 nan " istringstream sin (" 1 this 5.5 is a test -3.2 a"); optional<double> token; const double nan = numeric_limits<double>::quiet_NaN (); while (sin >> token) cout << token.get_value_or (nan) << " "; // output is "1 " istringstream sin (" 1 this 5.5 is a test -3.2 a"); double token; while (sin >> token) cout << token << " "; I did submit a ticket with the final comment proposing code that is (maybe?) a solution to this refinement. ( https://svn.boost.org/trac/boost/ticket/2659 ) Please pardon any guffaws I made in replies to that ticket, I'm still learning about the nuts and bolts of streams and boost as I go. However there is still one problem, and this brings us back to lexical_cast. Consider this example: int an_invalid_uint = -1; unsigned i = lexical_cast<optional<unsigned> > (an_invalid_uint).get_value_or (0); I believe we should expect this to store 0 in i, but instead it will throw a bad_lexical_cast exception even with my proposed revision to optional_io.hpp. A possible solution is a specialization for optional<Target> somewhere in lexical_cast.hpp that would replace code that looks something like this (pseudocode): do lexical_cast if failed to cast: throw exception With something like this: do lexical_cast if failed to cast: return optional<Target>() So is there any interest in this sort of refinement of optional's InputStreamable implementation or lexical_cast? -- Andrew Troschinetz Applied Research Laboratories