Casting of Templated Objects

This topic is 3505 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Is there some way around the issue of casting templated objects in C++? For example:
doSomething(vec<int> v);

vec<float> v1;
doSomething(v1);  // Error (T = float cannot be converted to T = int).

My current work-around solution involves some simple macros, and does something like this:
vec<float> v1;
vec<int> temp((int)v1.x, (int)v1.y);   // This is wasteful.
doSomething(temp);

How is this usually done? Thanks.

Share on other sites
You can make the object be able to automatically cast itself:
template<class T>class vec{public:	T x, y;	vec() : x(0), y(0) {}	//allow construction from any vec type	template<class Y>	vec( const vec<Y>& o ) : x(T(o.x)), y(T(o.y)) {}	//allow casting to any other type	template<class Y>	operator Y() { return Y(*this); }};vec<int> i;vec<float> fl = i;

[EDIT]RDragon1's suggestion below would be better (if applicable to your situation), as it side-steps the need to cast in the first place ;)

Share on other sites
You've stated that doSomething() only takes vec<int>'s. If you want it to take vec<T>'s then

template<typename T>
void doSomething( vec<T> const& vec )
{
}

Share on other sites
That's pretty much how it's done. Although you could shorten it to

vec<float> v1;
doSomething(vec<int>((int)v1.x, (int)v1.y));

EDIT: Ignore that code I put here before. My brain failed and I imagined C++ constructs that didn't exist. Do it like Hodgman says :)

[Edited by - hh10k on May 15, 2008 12:43:54 AM]

Share on other sites
That's not "how it's done" at all.

If you're writing an algorithm, it should take iterators as arguments. If you had done that correctly this problem would have never come up.

Otherwise, the algorithm was written wrong and should have taken a vec<T> as an argument instead of a vec<int>

Share on other sites
Quote:
 Original post by RDragon1That's not "how it's done" at all.If you're writing an algorithm, it should take iterators as arguments. If you had done that correctly this problem would have never come up.

He's not talking about std::vector, he's talking about a 2d vector. There's no iterators involved there at all. And I don't think you should tell him to template doSomething unless it actually does something generic to a type T. To me he just wanted a quick way to convert a float vector to an integer one, which happens sometimes.

Share on other sites
Thanks for the replies.

Re: hh10k - The code works great, except it makes it slightly dangerous :P Explicit cannot be used on the conversion operator, so the only way to do it is implicitly - which is not a good thing. (I see you just removed the code, probably for that very reason).

Re: RDragon1 - It's not really an algorithm problem. The situation comes up frequently, especially when dealing with simple data types.

After thinking about it, I think the best solution is to just stick toFloat() and toInt() functions in my vec class. This gives me the convenience that I need, and keeps the safety of explicit conversions.

Share on other sites
Quote:
 Original post by DogganThanks for the replies.Re: hh10k - The code works great, except it makes it slightly dangerous :P Explicit cannot be used on the conversion operator, so the only way to do it is implicitly - which is not a good thing. (I see you just removed the code, probably for that very reason).Re: RDragon1 - It's not really an algorithm problem. The situation comes up frequently, especially when dealing with simple data types.After thinking about it, I think the best solution is to just stick toFloat() and toInt() functions in my vec class. This gives me the convenience that I need, and keeps the safety of explicit conversions.

If your function works on ints and floats explicitly, why wouldn't it work generically on any T that meets the requirements of your function?

Share on other sites
Quote:
 Original post by RDragon1If your function works on ints and floats explicitly, why wouldn't it work generically on any T that meets the requirements of your function?

According to the OP it only works on ints, not ints and floats.
Perhaps it's doing some operation in pixel coordinates, which are by definition whole numbers. In cases like that, there is no need to make it a type-agnostic function - seeing as internally it's just going to have to perform a cast to a whole number anyway...

Share on other sites
Re: RDragon1 - As explained by Hodgman, why should it operate on all types? The function is not meant to do that.

Also, now I can do something like this:
// Old way.vec2<int> v1(1, 1);vec2<float> temp((float)v1.x, (float)v1.y);vec2<float> v = temp * 2.5f;// New way.vec2<int> v1(1, 1);vec2<float> v = v1.to<float>() * 2.5f;

Overall, it is really just a matter of convenience (not an algorithm design problem). I am happy with the current solution.

Edit: here is the code -

template <typename T>class vec2 {public:	T x, y;...	template <typename Y> vec2<Y> to() const { return (vec2<Y> ((Y)x, (Y)y)); }};

[Edited by - Doggan on May 15, 2008 3:44:57 AM]

Share on other sites

This topic is 3505 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.