C++: Converting string to any type

Started by
10 comments, last by ApochPiQ 14 years, 8 months ago
Hi, I made a function for converting a string to any type, but discovered a problem with it. Here's the function:
//usage: double val = strtoval<double>("465498.654");
template<typename T>
T strtoval(const std::string& s)
{
  std::istringstream sstream(s);
  T val;
  sstream >> val;
  return val;
}
It works for converting a string to int, double, etc... But I want it to be very generic, so it should also convert a string to a string correctly. However, when T is std::string, like the input, then at the output, it returns a different string: it removes everything after the first space. So it appears std::stringstream tokenizes its contents and the result is that my function doesn't work properly. So std::stringstream does two things at the same time, while I only want one thing: the conversion (not the tokenization) I don't like template specialization as a solution, because then you're treating special cases and there can be many different types of strings and so on. Questions: 1) Is there any way in C++ to solve this problem? 2) Is there any way to make a stringstream not treat spaces specially, but just do the same to spaces as it does to other characters? 3) Is std::stringstream the only interface in the C++ standard to have this conversion of a string to an arbitrary type, or is there also something lower level available? [Edited by - ApochPiQ on August 15, 2009 1:28:27 PM]
Advertisement
Why are you writing your own when boost already has one written, one that is significantly better than yours I might add?

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

You can specialise for std::string instances. Or use boost::lexical_cast<>.
Yeah I know about lexical cast, it's overkill for my purposes though.

Why does nobody ever answer my question about whether or not the conversion function that std::stringstream uses, is also available in the C++ interface?

If it isn't, please say so if you know it.

I suppose since boost had to make such a huge header file to do it, means that it probably isn't...
I don't believe the mechanism for converting between arbitrary types exists at any level other than the C++ stream library.

For your needs (and if you are sure you don't want boost), template specialisation would probably be the simplest way. You would, however, need to specialise for std::string and probably various char pointer types.
Quote:Original post by Lode
Yeah I know about lexical cast, it's overkill for my purposes though.

Why does nobody ever answer my question about whether or not the conversion function that std::stringstream uses, is also available in the C++ interface?

If it isn't, please say so if you know it.

I suppose since boost had to make such a huge header file to do it, means that it probably isn't...


I don't see how it can be overkill, since it's doing exactly what you're asking for (which is what it was designed for). It's also significantly more robust, which is important since error control is damn important (you can claim that there will never be an error, but that doesn't make it true).

As per your question, you need to specialize it, or just plain overload it, to handle the special cases.

Assuming no wide char types, you will need to specialize on any form of:
char [const] * [const]
std::string [const] &
If you do want wide char support, then you need to include the wchar_t/std::wstring variants as well (tchar/tstring typedefs help out a lot here if you change it based on compilation model). Note that using std::tr1/boost type_traits here can save time here...at the cost of complexity.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Ok, thanks, I went with the template specialization then, which will be fine for me, if any new problem pops up I'll go use lexical_cast because then the solution to my problem would probably be as complex as lexical_cast itself is anyway =)

Sorry for sounding nervous in above posts. I was trying to look for the simplest solution to do this, I'm in disagreement with the developers of C++ over the idea to put the conversions from/to strings, in the streams interface and nowhere else. It's C++ though, so of course the solution isn't going to be simple! And I can accept that. It's a beautiful language.
Please do not mark threads as "solved" in the General Programming forum.

Thanks! [smile]

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Quote:Original post by ApochPiQ
Please do not mark threads as "solved" in the General Programming forum.

Thanks! [smile]


I didn't want people to read it anymore because I upset some people with this thread appearantly :( In fact I wish this thread was just deleted.
Quote:Original post by Lode
I didn't want people to read it anymore because I upset some people with this thread appearantly :( In fact I wish this thread was just deleted.

Er, what? Who -- other than yourself, apparently -- did you upset?

This topic is closed to new replies.

Advertisement