Jump to content
  • Advertisement
Sign in to follow this  
CoreMeltdown

C++ Template Function Specialization

This topic is 4811 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

Hi, consider the following sample function:
template <class T1, class T2>
Vec3<T1> Convert(const Vec3<T2> & v) {
  return Vec3(T1(v[0]), T1(v[1]), T1(v[2]));
}

As you can argue, it simply convert from a Vec3 of some type to a Vec3 of another type. Now suppose I want to specialize the template in order to avoid cycle-wasting operations when T1 and T2 are the same (well, the above example is trivial, I think some compiler should be smart enough to optimize...). However, I'd like to code a specialization of the form:
template <class T>
Vec3<T> Convert<T, T>(const Vec3<T> & v) { // <-- here is the "syntax" question
  return v;
}

Does C++ allow such kind of specialization on non-member functions? If it does, what's the right syntax? Thank you :)

Share this post


Link to post
Share on other sites
Advertisement
You can't partially specialize template functions; however you can do that with inner classes, or structs.

The syntax would be something like:


template <typename T1, typename T2>
struct Convert{

Vec3<T1> convert(const Vec3<T2> & v)
{
return Vec3(T1(v[0]), T1(v[1]), T1(v[2]));
}
};

template <typename T>
struct Convert<T,int>{

Vec3<T> convert(const Vec3<int> & v)
{
return v;
}
};

Share this post


Link to post
Share on other sites
And you can again put a function template to act as a front-end:

namespace detail
{
template <typename T1, typename T2>
struct converter
{
typedef Vec<T1> result_type;
typedef Vec<T2> argument_type;

static result_type convert()(const argument_type& arg)
{
return result_type(T1(arg[0]), T1(arg[1]), T1(arg[2]));
}
};

template <typename T>
struct converter<T,T>
{
typedef Vec<T> result_type;
typedef Vec<T> argument_type;

static result_type convert()(const argument_type& arg)
{
return arg;
}
};
}

template<class T1, class T2>
typename detail::converter<T1,T2>::result_type convert(const T2& arg)
{
return detail::converter<T1,T2>::convert(arg);
}


The advantage of using the result_type typedef is that you could have converter<T,T> return a const Vec<T>& rather than a Vec<T> if you wanted to, and the client code wouldn't be any wiser.

Share this post


Link to post
Share on other sites
You could overload the function if you took both vectors as arguements, but I think the best solution to this particular problem is an explicit templatized constructor in the vec3 class. The normal conversion then would invoke the regular copy ctor and conversion from another vector would invoke your template ctor.


template<typename T>
struct Vec3
{
Vec3() {}
Vec3(T x, T y, T z) : x(x), y(y), z(z) {}
Vec3(const Vec3& copy) : x(copy.x), y(copy.y), z(copy.z) {}

template<typename S>
explicit Vec3(const Vec3<S>& copy) : x(copy.x), y(copy.y), z(copy.z) {}
};


Vec3<int> origin(0,0,0);

Vec3<float> origin2(Vec3<float>(origin));

Share this post


Link to post
Share on other sites
Tnx all :)

@Verg:
Yes, but in your sample code you assumed we already know one of the two template type arguments, and this is not my case.

@Shannon Barber
Your solution should be the best one in this simple case, but the example I shown was only for explanatory purpose. (consider, for the sample, if i can't modify the Vec3 definition...)

@Fruny
I heard/maybe knew that partial template specialization is not allowed on non-member functions. However, I think your solution is what I was searching and it seems quite elegant :)

Thanx all you guys!!!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!