This question actually bears little relevance to what I'm doing, but it did make me curious.
I have a color class called IColor, which extends from an IColorBase template class like:
typedef IColorBase<float> IColor;
IColorBase is a generic base class that provides the usual constructors and operator overloading and not much else. What got me interested, though, was handling a cross-type copy constructor like:
IColor color = RGB(0, 255, 0);
RGB() is a macro that splices byte components into a DWORD. The copy constructor looks like this:
IColorBase(DWORD& clr) { BYTE* _c = (BYTE*)&clr; r = _c[0] / 255.f; g = _c[1] / 255.f; b = _c[2] / 255.f; a = 1; }
My question, however, has to do with multi-type copy constructors. Let's say I also have:
typedef IColorBase<BYTE> IRGBA;
Whose copy constructor would look like this:
IColorBase(DWORD& clr) { BYTE* _c = (BYTE*)&clr; r = _c[0]; g = _c[1]; b = _c[2]; a = 255; }
Including two constructors that take the same input argument type, however, doesn't make sense without a specific type declaration. In other words, I'd need something like this:
IColorBase<float>(DWORD clr) { BYTE* _c = (BYTE*)&clr; r = _c[0] / 255.f; g = _c[1] / 255.f; b = _c[2] / 255.f; a = 1; }
IColorBase<BYTE>(DWORD clr) { BYTE* _c = (BYTE*)&clr; r = _c[0] / 255.f; g = _c[1] / 255.f; b = _c[2] / 255.f; a = 1; }
Which, of course, doesn't work. Is it possible to provide type-aware constructors like this or does the standard not allow it at all? After all, it's possible for assignment operators.
A templated cross-type copy constructor question
I looks like you're looking for template specialization, and you've almost got the syntax right:
template<class T> struct Color
{
Color(uint i);
T r,g,b,a;
};
template<> Color<float>::Color(uint i) { r = (i&0xFF)/255.0f; }
template<> Color<ubyte>::Color(uint i) { r = (i&0xFF); }
I have a color class called IColor, which extends from an IColorBase template class like:
typedef IColorBase<float> IColor;
That's not quite an "extension" ("extension" implies it inherits from [font=courier new,courier,monospace]IColorBase[/font]). That's just a normal "[font=courier new,courier,monospace]IColor[/font] is a typedef for [font=courier new,courier,monospace]IColorBase<float>[/font]."
RGB() is a macro that splices byte components into a DWORD. The copy constructor looks like this:
IColorBase(DWORD& clr) { BYTE* _c = (BYTE*)&clr; r = _c[0] / 255.f; g = _c[1] / 255.f; b = _c[2] / 255.f; a = 1; }
That's not a copy constructor. It's just a normal constructor that takes a [font=courier new,courier,monospace]DWORD[/font]. Also, you should make it a [font=courier new,courier,monospace]const DWORD&[/font] because you can't bind a non-const reference to a temporary. Actually, you probably want to just take out the reference all together and just make it a normal [font=courier new,courier,monospace]DWORD[/font]. There won't be any benefit here from using a reference.
Also, I wish you made [font=courier new,courier,monospace]RGB()[/font] an inline function and not a macro... I hate macros. They have no respect for namespace scope or anything.
Whose copy constructor would look like this:
IColorBase(DWORD& clr) { BYTE* _c = (BYTE*)&clr; r = _c[0]; g = _c[1]; b = _c[2]; a = 255; }
Again, not a copy constructor.
Including two constructors that take the same input argument type, however, doesn't make sense without a specific type declaration. In other words, I'd need something like this:
IColorBase<float>(DWORD clr) { BYTE* _c = (BYTE*)&clr; r = _c[0] / 255.f; g = _c[1] / 255.f; b = _c[2] / 255.f; a = 1; }
IColorBase<BYTE>(DWORD clr) { BYTE* _c = (BYTE*)&clr; r = _c[0] / 255.f; g = _c[1] / 255.f; b = _c[2] / 255.f; a = 1; }
Which, of course, doesn't work. Is it possible to provide type-aware constructors like this or does the standard not allow it at all? After all, it's possible for assignment operators.
Hmmm... I don't see any difference between the two? Did you intent for the constructors for [font=courier new,courier,monospace]IColorBase<float>[/font] and [font=courier new,courier,monospace]IColorBase<BYTE>[/font] to be exactly identical? Because I would've thought [font=courier new,courier,monospace]IColorBase<BYTE>[/font]'s constructor would've looked something like this:
[font=courier new,courier,monospace]IColorBase<BYTE>(DWORD clr) { BYTE* _c = (BYTE*)&clr; r = _c[0]; g = _c[1]; b = _c[2]; a = 255; }[/font]
If this is indeed what you intended, you could use a helper kind of like this:
template <typename T>
struct IColorBaseHelper;
template <>
struct IColorBaseHelper<float>
{
static const float max = 1.0f; // You don't need min or max now, but this shows
static const float min = 0.0f; // you that you can put useful stuff here
static const float dword_convert = 255.0f;
};
template <>
struct IColorBaseHelper<BYTE>
{
static const BYTE max = 255; // You don't need min or max now, but this shows
static const BYTE min = 0; // you that you can put useful stuff here
static const BYTE dword_convert = 1;
};
template <typename T>
class IColorBase
{
T r, g, b, a;
public:
IColorBase(const DWORD clr) :
r((clr & 0x000000ff) / IColorBaseHelper<T>::dword_convert),
g(((clr & 0x0000ff00) >> 8) / IColorBaseHelper<T>::dword_convert),
b(((clr & 0x00ff0000) >> 16) / IColorBaseHelper<T>::dword_convert),
a(((clr & 0xff000000) >> 24) / IColorBaseHelper<T>::dword_convert) // Why not have RGB() set alpha to 100%?
{
}
};
The nice thing about this is that it doesn't require you to template-specialize the entire class, and allows you to just template-specialize the relevant part(s).
Thanks for the replies, guys! I could probably have take it myself from "template specialization", though.
Cornstalks - you're right about it not being a copy constructor. In this case the word of the law does defeat the spirit of it
Cornstalks - you're right about it not being a copy constructor. In this case the word of the law does defeat the spirit of it
Did you intent for the constructors for IColorBase<float> and IColorBase<BYTE> to be exactly identical?
[/quote]
Yeah - that's a copy-paste thing.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement