我可以对(非成员)函数使用部分模板专门化吗?

时间:2009-12-25 18:30:51

标签: c++ templates partial-specialization

我正在尝试对(非成员)函数使用部分模板特化,而我正在绊倒语法。我已经在StackOverflow中搜索了其他部分模板特化问题,但这些问题涉及类或成员函数模板的部分特化。

首先,我有:

struct RGBA {
    RGBA(uint8 red, uint8 green, uint8 blue, uint8 alpha = 255) :
        r(red), g(green), b(blue), a(alpha)
    {}

    uint8 r, g, b, a;
};

struct Grayscale {
    Grayscale(uint8 intensity) : value(intensity) {}

    uint8 value;
};

inline uint8 IntensityFromRGB(uint8 r, uint8 g, uint8 b) {
    return static_cast<uint8>(0.30*r + 0.59*g + 0.11*b);
}

// Generic pixel conversion.  Must specialize this template for specific
// conversions.
template <typename InType, typename OutType>
OutType ConvertPixel(InType source);

我可以完全专门化ConvertPixel来制作RGBA到灰度转换功能,如下所示:

template <>
Grayscale ConvertPixel<RGBA, Grayscale>(RGBA source) {
    return Grayscale(IntensityFromRGB(source.r, source.g, source.b));
}

我可以想象有更多像素类型可以提供红色,绿色和蓝色,但可能采用不同的格式,所以我真正想做的是通过为{{Grayscale指定部分特化1}}并且仍然允许各种OutType s。我尝试过各种各样的方法:

InType

但是(Microsoft VS 2008 C ++)编译器拒绝它。

我正在尝试什么?如果是这样,那么正确的语法是什么?

3 个答案:

答案 0 :(得分:8)

C ++不允许对函数模板进行部分特化。

它甚至不允许成员函数模板的部分特化。当您定义一个函数时,该函数是类模板的部分特化的一部分,这可能看起来有点像您已经部分专门化了成员函数。但你还没有。

Herb Sutter discusses partial specialization

答案 1 :(得分:5)

可以使用class partial specialization:

template<class A, class B>
struct Functor {
    static A convert(B source);
};

template<class B>
struct Functor<GrayScale, B> {
    static GrayScale convert(B source) {
         return Grayscale(IntensityFromRGB(source.r, source.g, source.b));
    }
};

// Common function
template<class A, class B>
A Convert(B source) {
   return typename Functor<A,B>::convert(source);
}

答案 2 :(得分:3)

部分专业化是一种仅适用于类,而不是自由函数或成员函数的概念。你可能想要做的只是提供函数(或成员函数)重载,这类映射到部分和完全特化为类做的。