2009-12-25 3 views
3

Я пытаюсь использовать частичную специализацию шаблона для функции (не являющейся членом), и я могу отключиться от синтаксиса. Я искал 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 для OutType и по-прежнему допускать множество InType. Я пробовал различные подходы вроде этого:

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

Но компилятор (Microsoft VS 2008 C++) отклоняет его.

Является ли то, что я пытаюсь сделать возможным? Если да, то какой правильный синтаксис?

+1

вы не можете. Использовать перегрузку – KeatsPeeks

ответ

5

Это возможно с помощью класса partitial специализации:

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

Отлично. Спасибо! –

7

C++ не позволяет частичную специализацию шаблонов функций.

Он даже не допускает частичную специализацию шаблонов функций-членов. Когда вы определяете функцию, которая является частью частичной специализации шаблона класса, это может немного походить на то, что вы частично специализировали функцию-член. Но вы этого не сделали.

Herb Sutter discusses partial specialization

+0

Спасибо за ссылку! –

2

Частичная специализация это понятие, которое относится только к классам, а не свободных функций или функций-членов. То, что вы, вероятно, хотите сделать, это просто перегрузка функций функции (или член-функции), какая именно карта, для какой частичной и полной специализации для классов.

Смежные вопросы