如何在模板与联合之间进行继承? [英] How to have inheritance between template with union?
问题描述
我有以下两个对象.我想知道是否有一种方法可以将 Pixel
作为 PixelBGR
的基类,以便任何运算符(+、-、*、/、[] 等)都可以无需重新定义即可使用?
I have the following two objects. Im wondering if there is a way to have Pixel
as a base class of PixelBGR
so that any operator (+,-,*,/, [], etc.) could be used without redefining them ?
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: As suggested by πάντα ῥεῖ, here more details about what Im trying to do.
我正在尝试创建一个通用类 Pixel
,它将成为处理任何类型或大小的模板.
Im trying to have a generic class Pixel
, which will be template to handle any type or size.
通常是 1,2,3,4,8 或 16.该类定义了一些 operator
如 +,-,* 等.
The usual are 1,2,3,4,8 or 16. The class with defines some operator
such as +,-,*, etc.
由于大多数时候Pixel
是一个BGR像素,我想定义快速访问r
,g
和 b
以避免混淆,但仍将其存储为 BGR.
Since most of the time, the Pixel<T,3>
is a BGR pixel, I would like to define rapid access to r
,g
and b
to avoid confusion, but still store it as BGR.
但是派生类也应该提供基于 N
的通用操作符.
But the derived class should also provide the Operator which will be generic based on N
.
EDIT2:通过阅读 SergeyA 的评论,我忘了说结构 Pixel
不能改变大小.
EDIT2: By reading the comment of SergeyA, I forgot to say that the struct Pixel
must not change size.
所以我认为 balki 答案是最好的,通过使用成员函数.我试图用变量来避免太多的字符 ie: 添加 (),但它似乎太复杂了.我仍在研究 CRTP,但我不太了解,我正在阅读.
So I think balki answer is the best, by using member function. I was trying to make it with variables to avoid too much char ie: adding the (), but it seems to be too complicated for nothing. I still investigating CRTP, but I dont get it well, Im reading on that.
推荐答案
首先感谢大家的建议,特别感谢@Constantinos Glynos、@balki 和@SergeyA 提供的示例,这些帮助我实现了符合我需求的解决方案.
First thanks to all of you for advise, and special thanks to @Constantinos Glynos, @balki and @SergeyA for the example they provide, those help me to achieve a solution that match my need.
我实现了 BGR 和 BGRA 以表明 N 工作正常,现在我只需要实现我需要的所有运算符和功能.
I implemented the BGR and BGRA to show that the N works fine, now I just need to implement all the operator, and functions that I require.
请随时编辑,或告诉我这里是否有问题.
像素.h
#include <cstdio> // std::size_t
#include <iostream> // std::cout
template<typename T, std::size_t N, template<typename, std::size_t> class B >
struct Pixel
{
T ch[N];
// ==============================================================
// Overload the accessor (so .ch[0] == direct access with [0].
T& operator[](std::size_t x){ return ch[x]; }
// ==============================================================
// Copy-assignement
Pixel& operator=( const Pixel &t )
{
for ( int i = 0; i < N; i++ )
ch[i] = t.ch[i];
return *this;
}
// ==============================================================
// Operator
B<T, N> operator+( const B<T, N> &t )
{
B<T, N> tmp;
for ( int i = 0; i < N; i++ )
tmp[i] = ch[i] + t.ch[i];
return tmp;
}
B<T, N> operator-( const B<T, N> &t )
{
B<T, N> tmp;
for ( int i = 0; i < N; i++ )
tmp[i] = ch[i] - t.ch[i];
return tmp;
}
template<typename T, std::size_t N, template<typename, std::size_t> class B >
friend std::ostream& operator<<( std::ostream& os, const Pixel &t );
};
// To print the vector
template<typename T, std::size_t N, template<typename, std::size_t> class B >
std::ostream& operator<<( std::ostream& os, const B<T, N> &t )
{
os << "Pixel: (" << t.ch[0];
for ( int i = 1; i < N; i++ )
os << ", " << t.ch[i];
os << ")";
return os;
}
template<typename T, std::size_t N = 3>
struct BGR : Pixel<T, N, BGR>
{
T& b() { return ch[0]; }
T& g() { return ch[1]; }
T& r() { return ch[2]; }
};
template<typename T, std::size_t N = 4>
struct BGRA : Pixel<T, N, BGRA>
{
T& b() { return ch[0]; }
T& g() { return ch[1]; }
T& r() { return ch[2]; }
T& a() { return ch[3]; }
};
Main.cpp
int main() {
std::cout << "Sizeof a float BGR: " << sizeof(BGR<float>) << std::endl;
std::cout << "Sizeof a float BGRA: " << sizeof(BGRA<float>) << std::endl;
BGR<int> p;
p.r() = 25;
p.g() = 14;
p.b() = 58;
std::cout << p << std::endl;
std::cout << p[0] << " , " << p[1] << " , " << p[2] << std::endl;
std::cout << p.b() << " , " << p.g() << " , " << p.r() << std::endl;
BGR<int> q;
q = p;
std::cout << q[0] << " , " << q[1] << " , " << q[2] << std::endl;
BGR<int> res1;
res1 = q + p;
std::cout << res1.r() << " , " << res1.g() << " , " << res1.b() << std::endl;
BGR<int> res2;
res2 = q - p;
std::cout << res2.r() << " , " << res2.g() << " , " << res2.b() << std::endl;
BGRA<float> a;
a.r() = 255.0f;
a.g() = 0.0f;
a.b() = 0.0f;
a.a() = 128.5f;
BGRA<float> b = a;
std::cout << a << std::endl;
return 0;
}
这篇关于如何在模板与联合之间进行继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!