Can I use partial template specialization for a (non-member) function?

和自甴很熟 提交于 2019-12-21 05:18:05

问题


I'm trying to use partial template specialization on a (non-member) function, and I'm tripping up on the syntax. I've searched StackOverflow for other partial template specialization questions, but those deal with partial specialization of a class or member function template.

For a starting point, I have:

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

I can do a complete specialization of ConvertPixel to make an RGBA to Grayscale conversion function like this:

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

I'll conceivably have more pixel types that offer red, green, and blue, but perhaps in a different format, so what I'd really like to do is a partial specialization by specifying Grayscale for OutType and still allow for a variety of InTypes. I've tried a variety of approaches like this:

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

But the (Microsoft VS 2008 C++) compiler rejects it.

Is what I'm attempting possible? If so, what's the right syntax?


回答1:


It is possible using class partitial 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:


C++ does not allow partial specialization of function templates.

It doesn't even allow partial specialization of member function templates. When you define a function which is part of a partial specialization of a class template, that might look a bit like you've partially specialized the member function. But you haven't.

Herb Sutter discusses partial specialization




回答3:


Partial specialization is a concept that only applies to classes, not free functions or member functions. What you probably want to do is just provide function (or member function) overloads, which sort of map to what partial and full specializations do for classes.



来源:https://stackoverflow.com/questions/1961659/can-i-use-partial-template-specialization-for-a-non-member-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!