
Dave Dribin wrote:
On May 5, 2005, at 2:55 PM, Andrey Melnikov wrote:
Semantically convert_to is a different operation. Safe C++ way to do itoa has nothing to do with serialization.
Working with windows and configuration files, in my experience, at least, requires handling of invalid values. They are the normal case, not an exceptional case. And from reading the lexical_cast documentation, you'd think this is the library to use. Apart from the name containing "cast", lexical_cast does what I need: converting numbers to and from strings.
I agree with the need for safe conversion function with error indication, and with other lexical_cast design goals stated in documentation. I just don't want slow approach with temporary std::stringstream to be used for simple conversions. Instead, I want faster lexical_cast() specializations for built-in types, and additional lexical_cast_nothrow() function.
I think we can leave lexical_cast alone as it is, but add separate functions for safe conversions between ascii and binary representation of numbers. These functions should be fast and properly named according to their semantic. Performance requirement can also force us to implement additional interface with error flag instead of throwing exceptions. convert_to<int>("abc") can be so fast that in some applications overhead of throwing an exception will be very noticeable.
That would work, as well. But I'm thinking that convert_to would need to fall back to lexical_cast for conversion that do not contain a string. If we want to concentrate on the conversion to and from strings, maybe names like string_to and to_string would be more appropriate:
int n = string_to<int>("50"); int httpPort = string_to<int>("invalid conversion", 80);
And the converse:
string message = "Connecting to server: " + host + ":" + to_string(80);
I introduced to_string and from_string not only because I dislike "lexical_cast" name. The main reason is that current extensibilty framework is too heavyweight. So I proposed to introduce a separate family of functions which wouldn't require operator << and operator >> (or, more precicely, ostream/stringstream) for extensibility. For example, an UDT could just specialize an internal template class to allow faster conversion using std::string, or use older extensibility framework with overloaded operator >>. On the one hand, implementation which uses std::string, can be much faster than implementation which uses std::stringstream. On the other hand, std::stringstream provides convenient methods to facilitate serialization of complex types. Can we stay with just lexical_cast, add lexical_cast_nothrow and lexical_cast_default, and have both extensibility methods implemented in a non-conflicting way?
Actually, to_string cannot have an invalid conversion case, can it? It seems only going from a string can cause that.
In case of user types it can. For example, an overloaded operator << can refuse to serialize an object with invalid state.
And as for performance being an issue, it probably is in some cases. In the cases where I've used string to int conversions and vice vera, performance has not been critical and stringstreams have been just fine, though. I started using lexical_cast because it made my stringstream code easier to read.
Well, function performance is always an issue only in some usage scenarios. I understand that parsing config files doesn't have high performance requirements. I actually don't use lexical_cast directly. I use boost::date_time on large data volumes, and it happened that overhead of using boost::date_time was significant even despite I/O was the bottleneck too. Performance profiling showed that date_time was among critical functions. When I looked inside the source, it turned out that I could increase overall performance a lot by patching boost::lexical_cast and boost::tokenizer libraries... Now I want these issues to be fixed in main boost source tree so I won't need to patch next releases myself to get the performance I need. Andrey