>> mp_image<T, NC>::SquareBlur<T2>(uint radius);
I don't think you want the :: there, do you?
>> is there any way to determine T2 automatically instead of having to provide it in each call
Maybe, although I would provide the function that let's the caller specify the type and then provide a second version that let's you figure it out (and then calls the three template argument version).
To figure out what type to use, you can try to use the values in numeric_limits. If you want to restrict which data types can be sent to that function, you can also create a helper class that uses template meta-programming to return the proper type. I would have to spend some time on it to get the syntax correct, but here is the basic idea:
If the user wants an unsupported type they have to call the three template version directly.
template <typename T>
// Something should be added here that causes an error if this is instantiated or used,
// perhaps just leaving the next line commented out will work:
// typedef int BiggerType;
typedef uint32 BiggerType;
typedef double BiggerType;
// ... etc. for all allowed types
template<class T, uint NC, class T2>
mp_image<T, NC> SquareBlur<T2>(uint radius); // implemented elsewhere
template<class T, uint NC>
mp_image<T, NC> SquareBlur(uint radius)
return SquareBlur<T, NC, typename TypeConverter<T>::BiggerType>(radius);