Sign in to follow this  
Chris81

Automagic conversions in C++

Recommended Posts

Hello, I just thought I would post this because I am finding it very usefull. It's an automatic conversion function. Not sure how it holds up speed-wise, but then again, datatype conversion isn't something you should be doing every frame, right? Anyway, here is the source:
	// Conversion
	template< class TO, class FROM >
	TO ConvertTo( const FROM &val )
	{
		TO ret;
		std::stringstream ss;
	
		ss << val;
		ss >> ret;
	
		return ret;
	}


Here is how to use it:
float f = 123.45;
double d = 88.30;
string s = "500";
 
string str = ConvertTo< string >( d );       // str = "88.30"
int i = ConvertTo< int >( s );               // i = 500
 
void foo( string s )
{
   // s = "123.45"
}
 
foo( ConvertTo< string >( f ) );


You can even use this on user-defined objects if you override stream operators << and >>. Pretty neat, huh?

Share this post


Link to post
Share on other sites
Wow, I, that, uuh...

that's really cute, gj man

I might have written it like this:

template<class FROM, class TO>
void CONV(const FROM & f, TO & t){
std::stringstream ss;
ss << f;
ss >> t;
}

Though, to be fair, this is only an improvement in terms of reducing the total number of characters written by the programmer (I'm a firm believer in having compact code).

Share this post


Link to post
Share on other sites
Quote:

Original post by Chris81

// Conversion
template< class TO, class FROM >
TO ConvertTo( const FROM &val )
{
TO ret;
std::stringstream ss;

ss << val;
ss >> ret;

return ret;
}




You can even use this on user-defined objects if you override stream operators << and >>.

Pretty neat, huh?


You are ignoring error states in the conversion. More correct implementation:

template<typename Target, typename Source>
Target ConvertTo(const Source &val)
{
Target ret;
std::stringstream ss;

if (!(ss << val && ss >> ret))
throw std::runtime_error("Avast!");

return ret;
}




Replace Avast with a more useful error message, or a custom exception class.

This conversion operation is actually a slightly modified version of an earlier version of boost's lexical_cast - the current lexical_cast has been improved for more correct type conversions for some of the more tricky types, and I'd suggest using that instead. Get it here.

Edit: Fixed quote - this thing obviously doesn't like placing source tags inside quotes. [headshake]

Share this post


Link to post
Share on other sites
There is another problem I see: once the correct operators >> and << are defined, you loose the control you have on the conversion. For example, imagine you are defining these operators for a structure S:

struct S
{
int a[5];
float b;
std::string c;
};

There is no intelligent way to convert an int to an S instance. The stream operators are still useful to serialize S instances. I bet you can see the problem coming...

Conclusion: your idea is a good way to bypass type safety. As such, it can be dangerous and ide serious bugs.

Regards,

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Emmanuel Deloget
Conclusion: your idea is a good way to bypass type safety. As such, it can be dangerous and ide serious bugs.

Regards,


Thanks for the input, and I agree. However, I never intended to suggest that. Only if you have objects that routinely and easily convert from one to the other would it be used in this way.

Plus, in those cases, you are explicitly doing the conversion, so you should know if it's safe or not.

I do agree with the muer though, that it should have error checking.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this