我能为非成员函数使用部分模板特化吗?

4

我想在一个(非成员)函数上使用部分模板特化,并且我在语法上遇到了困难。我在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));
}

我可能会有更多像素类型,提供红色、绿色和蓝色,但可能是以不同的格式呈现,所以我真正想做的是通过指定 OutTypeGrayscale 部分特化,同时仍然允许多种 InType。我尝试了各种方法,例如:

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

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

我所尝试的是否可能?如果可能,正确的语法是什么?

3个回答

8

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

它甚至不允许对成员函数模板进行部分特化。当你定义一个函数作为类模板的部分特化的一部分时,可能看起来有点像你已经部分特化了成员函数。但实际上没有。

Herb Sutter 讨论了部分特化问题


6

可以使用类部分特化实现:

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

3

部分特化是一个只适用于类,而不适用于自由函数或成员函数的概念。你可能想要做的就是提供函数(或成员函数)重载,这有点类似于部分和完全特化对类所做的映射。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接