Sign in to follow this  

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by RDragon1
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.


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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Doggan
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.


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 this post


Link to post
Share on other sites
Quote:
Original post by RDragon1
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?

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 this post


Link to post
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 this post


Link to post
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.

If you intended to correct an error in the post then please contact us.

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