简体   繁体   中英

Partial specialising function template with templated argument

I've got a template function (for the sake of simplification, let's call it "add")

template<typename T>
inline T add(const T a, const T b)
{
    return a+b;
}

I can specialise it for certain types, but what I'd like to do is specialise it for a templated type.

In my case, my templated type is called Vec2<T> . It's a 2-dimensional trigonometric vector (as in x & y, rather than c++ vector!)

What I'd like to do is specialise my add function for the generic case of Vec2<T> , rather than have to specialise for each type that Vec2 may be used with.

The library that Vec2<T> comes from has typedefs for V2d (double), V2f (float) and V2i (int).

I can specialise for each of these using something like:

template<>
inline V2f add<V2f>(const V2f a, const V2f b)
{
    return V2f(a.x + b.x, a.y + b.y);
}

However, what I'd like to be able to do, and this is where I've found myself stuck, is something like:

template<typename S>
inline Vec2<S> add<Vec2<S> >(const Vec2<S> a, const Vec2<S> b)
{
    return Vec2<S>(a.x + b.x, a.y + b.y);
}

I feel like there must be a way of doing this, but I'm struggling to find the right syntax for it.

Partial template specialization is not allowed for function templates (it only works with class templates). You could use function template overloading instead:

template<typename S>
inline Vec2<S> add(const Vec2<S>& a, const Vec2<S>& b)
{
    return Vec2<S>(a.x + b.x, a.y + b.y);
}

It'll be selected when you call add with all the instantiations of Vec2 as arguments.


It would be better to change the parameters to pass-by-const-reference to avoid copy.

You can't partially specialize function templates. But you can do it for class templates, so all your function needs to do is forward to one:

template<typename> struct add_impl;

template<typename T>
T add(const T a, const T b)
{
    return add_impl<T>::do_it(a, b);
}

template<typename T>
struct add_impl {
  static T do_it(const T a, const T b) { return a + b; }
};

template<typename S>
struct add_impl<Vec2<S> > {
  static Vec2<S> do_it(const Vec2<S> a, const Vec2<S> b) { 
    return Vec2<S>(a.x + b.x, a.y + b.y);
  }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM