我有以下两个对象。我想知道是否有办法拥有 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];
}
};
编辑:正如 πìντα ῥεῖ 所建议的,这里有更多关于我正在尝试做的事情的细节。
我想拥有一个通用类 Pixel
,这将是处理任何类型或大小的模板。
通常是 1、2、3、4、8 或 16。带有的类定义了一些 operator
。如+、-、*等
因为大多数时候,Pixel<T,3>
是一个 BGR 像素,我想定义快速访问 r
, g
和 b
为避免混淆,但仍将其存储为 BGR。
但是派生类还应该提供基于N
的泛型运算符。 .
EDIT2:通过阅读 SergeyA 的评论,我忘了说结构 Pixel
不得改变尺寸。
所以我认为 balki 答案是最好的,通过使用成员函数。我试图用变量来避免太多的字符即:添加(),但它似乎太复杂了。我仍在研究 CRTP,但我不太了解,正在阅读。
最佳答案
按照要求回答问题,这应该让 OP 重用运算符而没有任何未定义的行为:
#include <cstddef>
template<class T, std::size_t N>
struct Pixel
{
T ch[N];
inline T& operator[](const int x)
{
return ch[x];
}
Pixel& operator+= (const Pixel& ) { return *this;}
};
template<class T, std::size_t N>
Pixel<T, N> operator+ (const Pixel<T, N>& l, const Pixel<T, N>& r);
template<class T>
struct BgrPixel : Pixel<T, 3> {
using base = Pixel<T, 3>;
using base::base;
BgrPixel(const base& b) : base(b) { };
T& b = base::ch[0];
T& g = base::ch[1];
T& r = base::ch[2];
};
BgrPixel<int> a, b;
BgrPixel<int> c = a + b;
替代方案是将 b()、g() 和 r() 作为成员函数,但这需要您将它们作为函数访问。您还需要它们的 const 和非 const 版本。
但是,这样做的好处是结构的大小不会增加,并且复制分配会自然地工作(反过来,这可以通过提供自定义复制分配来解决)。
关于c++ - 如何在模板与 union 之间继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55462197/