I have some code that uses two different type of colours, 8 bit per channel and 16 bit per channel, each represented by a struct. In order to effectively reuse my code I have a template function that does some rendering with them. I would therefore like a templated function to grab the max value of a channel of my colours.
My initial attempt looked like this. I have only shown the specialization for 8 bpc
struct Pixel8
{
unsigned char r;
unsigned char g;
unsigned char b;
};
#define PIXEL8_MAX 255
template <class PIXEL>
auto getMax( ) -> decltype( PIXEL::r )
{
static_assert( sizeof(PIXEL) > 0, "getMax can only be called with a pixel type." );
}
template <>
auto getMax<Pixel8>( ) -> decltype( Pixel8::r )
{
return PIXEL8_MAX;
}
This would not compile with Visual studio 2012. I get the error
1> error C2785: ''unknown-type' getMax(void)' and 'char getMax(void)' have different return types 1> see declaration of 'getMax'
To me I feel that this should work but I have been unable to find any examples. There is one other question similar at Specialize function template with decltype trailing return type, but here the return type is the same for each specialization.
I have found a workaround which I will post as an answer so that others can benefit. However it is not very transparent so if someone can tell me if the code above is valid and this is a VC++ incompatibility or if it is not valid then why and how I can make it valid?
255
doesn't fit insigned char
(but does inunsigned char
).char
may be signed. – Jarod42static_assert
will always fire on some compilers because it doesn't depend on template parameters. – TartanLlamatraits
instead of plain functions. – Telokis