我有以下两个对象。我想知道是否有一种方法可以将Pixel
作为PixelBGR
的基类,以便可以使用任何操作符(+、-、*、/、[]等)而无需重新定义它们?
template<class T, std::size_t N>
struct Pixel
{
T ch[N];
inline T& operator[](const int x)
{
return ch[x];
}
};
template<class T>
struct PixelBGR
{
union
{
struct
{
T b;
T g;
T r;
};
T ch[3];
};
inline T& operator[](const int x)
{
return ch[x];
}
};
EDIT:正如π ντα ε所建议的,这里有更多关于我想做什么的细节。
我试图有一个泛型类Pixel
,这将是处理任何类型或大小的模板。
通常为1、2、3、4、8或16。带有的类定义了一些operator
,如+、-、* 等。
由于大多数情况下,Pixel<T,3>
是BGR像素,我希望定义快速访问r
、g
和b
以避免混淆,但仍将其存储为BGR。
但是派生类还应该提供Operator,它将是基于N
的泛型。
EDIT 2:通过阅读SergeyA的注解,我忘记了说结构体Pixel
一定不能改变大小。
所以我认为balki的答案是最好的,通过使用成员函数。我试图使它与变量,以避免太多的字符 * 即:添加()*,但似乎太复杂了。我仍在调查CRTP,但我不太明白,我阅读。
3条答案
按热度按时间8zzbczxx1#
回答所提出的问题,这应该给予OP操作符的重用,而没有任何未定义的行为:
另一种方法是将b()、g()和r()作为成员函数,但这需要将它们作为函数访问,还需要它们的常量和非常量版本。
然而,这样做的好处是结构体的大小不会增加,并且拷贝分配可以自然地工作(反过来,这可以通过提供自定义拷贝分配来解决)。
pinkon5k2#
在这种情况下,奇怪的循环模板模式(CRTP)会很好地工作。在CRTP中,派生类被用作基类的模板参数。大卫Vandevoorde和Nicolai M. Josuttis所著的C++模板-完整指南中的第16.3章奇怪的循环模板模式(CRTP)更详细地解释了这些事情。
从下面的评论中可以看出,使用
union{struct{...}...}
会导致未定义行为(UB),但对此有一些矛盾的观点。据我所知,它是一个gnu扩展,几乎所有编译器都支持它。例如,glm
经常使用union-structs
。作为替代方法,您可以为
r,g,b
变量使用别名(引用)。结果:
使用参考文献的示例:https://rextester.com/AZWG4319
使用union-struct的示例:https://rextester.com/EACC87146
cyej8jka3#
首先感谢你们所有人的建议,特别感谢@Constantinos Glynos、@balki和@SergeyA提供的示例,他们帮助我实现了符合我需求的解决方案。
我实现了BGR和BGRA,以显示N工作正常,现在我只需要实现我需要的所有运算符和函数。
请随意编辑,或告诉我是否有问题。
像素.h
主要.cpp