Search code examples
c++templatesstdis-same

Same Template struct, C++


Consider I have structs RGB and ARGB.

template<typename T>
struct RGB {
    T r,g,b;
};

template<typename T>
struct ARGB {
    T a,r,g,b;
}

Now I define them by following.

using RGB_888 = RGB<unsigned char>;
using RGB_Float = RGB<float>;
using ARGB_8888 = ARGB<unsigned char>;
using ARGB_Float = ARGB<float>;

At some point I want to convert from one rgb to another and from rgb to argb. So I do the following.

template<typename Source, typename Dest>
void convert(const Source& source, Dest& dest)
{

}

and it shall work like this.

RGB_888 rgb888{123,22,311};
RGB_Float rgbFloat;
convert<RGB_888,RGB_Float>(rgb888,rgbFloat);

RGB_888 rgb888(123,22,132};
ARGB_Float argbFloat;
convert<RGB_888,ARGB_Float>(rgb888,argbFloat);

The problem is that I cannot detect whether typename Source and typename Dest are from the same Color Model or not, and I need that for correct conversion. In other words if some typename T1 is a hybrid typename A<B> and another typename T2 is a hybrid typename A1<B1> How can I tell whether typename A and typename A1 are the same or not? If I had all A B A1 B1 typenames in my convert() function , I could tell by checking std::is_same<A<B>,A1<B>>::value But If I declare my function templates like that I'll end up unable to use convert<RGB_888,ARGB_Float>(rgb888,argbFloat); this signature (but I could use it with RGB and ARGB)

Please note: There are many other color models in my program, these are just for example.


Solution

  • It seems you want overloads

    template<typename Source, typename Dest>
    void convert(const RGB<Source>& source, RGB<Dest>& dest)
    {
    // ...
    }
    
    template<typename Source, typename Dest>
    void convert(const RGB<Source>& source, ARGB<Dest>& dest)
    {
    // ...
    }
    

    with usage

    RGB_888 rgb888{123,22,311};
    RGB_Float rgbFloat;
    convert(rgb888, rgbFloat);
    
    RGB_888 rgb888(123,22,132};
    ARGB_Float argbFloat;
    convert(rgb888, argbFloat);
    

    but output parameter is strange, I think you can do

    template <typename Dest, typename Source>
    RGB<Dest> toRGB(const RGB<Source>& source)
    {
    // ...
    }
    
    template <typename Dest, typename Source>
    ARGB<Dest> toARGB(const RGB<Source>& source)
    {
    // ...
    }
    

    With usage

    RGB_888 rgb888{123, 22, 311};
    RGB_Float rgbFloat = toRGB<float>(rgb888);
    
    RGB_888 rgb888(123, 22, 132};
    ARGB_Float argbFloat = toARGB<float>(rgb888);