Re: [boost] string_to/to_string (was: Re: Report from Berlin C++ Standards Committee meeting)

Martin Adrian wrote:
Reece Dunn <msclrhd <at> hotmail.com> writes:
What about converting to different string types, mainly std::string or std::wstring?
I use to_string and to_wstring but both actually comes from basic_to_string which is templated on StringT.
In my own stream class I have implemented c_str() so basic_to_string looks something like:
template <typename StringT, typename T> StringT basic_to_string(call_traits<T>::arg_type x) { myostream<StringT::char_type> os; os << x; return StringT(os.c_str()); }
What if StringT doesn't have a char_type define (such as const wchar_t *)? What if you have something like basic_string< char, case_insensitive< char > >? Or define a different allocator? You could have: typedef typename traits::char_type< StringT >::type char_type; typedef typename traits::char_traits< StringT >::type char_traits; typedef typename traits::allocator_type< StringT >::type allocator; std::basic_ostringstream< char_type, char_traits, allocator > os; os << x; return StringT( os.str().c_str());
template <typename T> std::string to_string(const T& x) { return basic_to_string<std::string, T> (x); }
That is similar to what I initially came up with.
template <typename T, typename SequenceT> T from_string(const SequenceT& seq) { T v; myistream<SequenceT::value_type> is(begin(seq), end(seq)); is >> v; if (istream_failed(is)) throw invalid_argument("from_string"); return v; }
People in this discussion have expressed a dislike of throwing exceptions on conversion failure w.r.t. lexical_cast. We could have a string_to and try_string_to, where the try_ version returns T and throws, while the other returns optional<T> and doesn't throw.
I am also working on implementing to_string and string_to :). Maybe we could combine our efforts and get to_string/string_to into Boost.
Sure. I can send you my code.
Great!
At the moment, my versions don't have locale support and string_to isn't returning optional<T>
I no fan of optional and prefer throw/default. I have not seen a situation where optional would be easier to use but many where it would be more difficult.
I haven't looked into using optional as I am not familiar with the library. Therefore, I am not qualified to answer questions regarding its usefulness in this situation :).
locale support is a must for me since I want to use to_string both for user messages (which uses global locale) and SQL statements (which uses classic + a special date facet).
Yeah. Others have requested this for lexical_cast. I was planning on adding versions which take a locale as a second parameter, but haven't gotten around to it yet. - Reece _________________________________________________________________ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/

What if StringT doesn't have a char_type define (such as const wchar_t *)?
(char_type should be value_type, which is part of the basic_string standard) How do you expect to_string to work with "const wchar_t*"? returning a pointer to a static buffer, dymaicly allocating it? In my class implementation I have a to_c_str() function which returns a pointer to the streams internal buffer. string_conversion<std::string> conv(somelocale, &std::hex); conv.to_string(123); //returns std::string conv.to_c_str(123); // returns const char*
What if you have something like basic_string< char, case_insensitive< char > ? Or define a different allocator?
Don't understand the question. basic_to_string should work fine with any string class that can be constructed from a "StringT::value_type*".
typedef typename traits::char_type< StringT >::type char_type; typedef typename traits::char_traits< StringT >::type char_traits; typedef typename traits::allocator_type< StringT >::type allocator; std::basic_ostringstream< char_type, char_traits, allocator > os; os << x;
What does the string's traits and allocator got to do with the stream? Is it so that just beacuse I use a pool allocator for my strings I automaticly want to use it for streams as well? It should probably be template <typename StringT, typename TraitsT, typename AllocatorT, typename T> StringT to_string(const T& x) { std::basic_ostringstream< StringT::value_type, TraitsT, AllocatorT > os; os << x; return StringT(os.str().c_str()); } but since you can't have default template parameters for functions it complicates usage a lot without adding much value. (My stream class also uses small string optimization so allocation rarly happens).
People in this discussion have expressed a dislike of throwing exceptions on conversion failure w.r.t. lexical_cast. We could have a string_to and try_string_to, where the try_ version returns T and throws, while the other returns optional<T> and doesn't throw.
My version allows you to specify what should be returned on error instead. try_string_to can then easily be implemented as: template <typename T, typename StringT> T try_string_to(const StringT& str) { return string_to<T, StringT>(str, T()); }
participants (2)
-
Martin Adrian
-
Reece Dunn