带有模板化参数的部分特化函数模板

Partial specialising function template with templated argument

本文关键字:函数模板 参数      更新时间:2023-10-16

我有一个模板函数(为了简化,我们称它为"add")

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

我可以为某些类型专门化它,但我想做的是为模板化类型专门化它。

在我的例子中,我的模板类型称为Vec2<T>。它是一个二维三角向量(如x &Y,而不是c++的vector!)

我想做的是将add函数专门用于Vec2<T>的一般情况,而不是必须专门用于Vec2可能使用的每种类型。

Vec2<T>来自的库有V2d (double)、V2f (float)和V2i (int)的类型定义。

我可以使用如下代码来专门处理这些:

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

然而,我希望能够做到的,也是我发现自己卡住的地方,是这样的:

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);
}

我觉得一定有一种方法可以做到这一点,但我正在努力寻找正确的语法。

函数模板不允许部分模板特化(它只适用于类模板)。你可以使用函数模板重载:

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);
}

当你用Vec2的所有实例化作为参数调用add时,它将被选中。


最好将形参改为pass-by-const-reference,以避免复制。

不能部分特化函数模板。但是你可以为类模板这样做,所以所有你的函数需要做的就是转发到一个:

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);
  }
};