【发布时间】:2021-03-10 11:46:53
【问题描述】:
嘿,我正在尝试用 c++ 实现Color space 逻辑。 正如您可能看到的,每个颜色空间都有其独特的颜色分量及其独特的范围和名称,因此我尝试先实现空间分量逻辑。
template<typename T, T min, T max>
struct SpaceComponent {
static constexpr T MIN = min;
static constexpr T MAX = max;
T value;
SpaceComponent() = default;
SpaceComponent(T value) : value(static_cast<T>(value)) {
}
operator T() const {
return value > MAX ? MAX : value < MIN ? MIN : value;
}
operator SpaceComponent<T, MIN, MAX>() const {
return SpaceComponent<T, MIN, MAX>(static_cast<T>(value));
}
inline bool operator==(const SpaceComponent &other) const {
return value == other.value;
}
inline bool operator!=(const SpaceComponent &other) const {
return !(*this == other);
}
inline bool operator>(const SpaceComponent &other) const {
return value > other.value;
}
inline bool operator<(const SpaceComponent &other) const {
return !(*this > other) && *this != other;
}
inline bool operator>=(const SpaceComponent &other) const {
return !(*this < other);
}
inline bool operator<=(const SpaceComponent &other) const {
return !(*this > other);
}
inline SpaceComponent &operator=(const T &elem) {
if (value == elem) {
return *this;
}
value = static_cast<T>(elem);
return *this;
}
inline SpaceComponent &operator=(const SpaceComponent &other) {
if (*this == other) {
return *this;
}
*this = other.value;
return *this;
}
inline SpaceComponent &operator++() {
*this = static_cast<T>(++value);
return *this;
}
inline SpaceComponent &operator--() {
*this = static_cast<T>(--value);
return *this;
}
inline SpaceComponent operator+(const T &elem) const {
SpaceComponent result;
result = static_cast<T>(value + elem);
return result;
}
inline SpaceComponent operator-(const T &elem) const {
SpaceComponent result;
result = static_cast<T>(value - elem);
return result;
}
inline SpaceComponent operator*(const T &elem) const {
SpaceComponent result;
result = static_cast<T>(value * elem);
return result;
}
inline SpaceComponent operator/(const T &elem) const {
SpaceComponent result;
result = static_cast<T>(value / elem);
return result;
}
inline SpaceComponent operator+(const SpaceComponent &other) const {
SpaceComponent result;
result = static_cast<T>(value + other.value);
return result;
}
inline SpaceComponent operator-(const SpaceComponent &other) const {
SpaceComponent result;
result = static_cast<T>(value - other.value);
return result;
}
inline SpaceComponent operator*(const SpaceComponent &other) const {
SpaceComponent result;
result = static_cast<T>(value * other.value);
return result;
}
inline SpaceComponent operator/(const SpaceComponent &other) const {
SpaceComponent result;
result = static_cast<T>(value / other.value);
return result;
}
inline SpaceComponent operator+=(const T &elem) {
*this = *this + elem;
return *this;
}
inline SpaceComponent operator-=(const T &elem) {
*this = *this - elem;
return *this;
}
inline SpaceComponent operator*=(const T &elem) {
*this = *this * elem;
return *this;
}
inline SpaceComponent operator/=(const T &elem) {
*this = *this / elem;
return *this;
}
inline SpaceComponent &operator+=(const SpaceComponent &other) {
*this = *this + other;
return *this;
}
inline SpaceComponent &operator-=(const SpaceComponent &other) {
*this = *this - other;
return *this;
}
inline SpaceComponent &operator*=(const SpaceComponent &other) {
*this = *this * other;
return *this;
}
inline SpaceComponent &operator/=(const SpaceComponent &other) {
*this = *this / other;
return *this;
}
};
通过这个逻辑,我可以创建我想要的任何类型的颜色组件,并且它不会退出它的范围(参见实现)。请注意,我将 MIN 和 MAX 静态保留,因为我不希望我的空间组件增加大小(想象一下,如果我这样做,我的 ram 中 4096x4096 图像的大小将是多少)。
然后我尝试实现不同的颜色空间
struct RGB {
SpaceComponent<unsigned char, 0, 255> r;
SpaceComponent<unsigned char, 0, 255> g;
SpaceComponent<unsigned char, 0, 255> b;
inline RGB operator+(const RGB &other) {
RGB rgb;
rgb.r = r + other.r;
rgb.g = g + other.g;
rgb.b = b + other.b;
return rgb;
}
};
struct ARGB {
SpaceComponent<unsigned char, 0, 255> a;
SpaceComponent<unsigned char, 0, 255> r;
SpaceComponent<unsigned char, 0, 255> g;
SpaceComponent<unsigned char, 0, 255> b;
inline ARGB operator+(const ARGB &other) {
ARGB argb;
argb.a = a + other.a;
argb.r = r + other.r;
argb.g = g + other.g;
argb.b = b + other.b;
return argb;
}
};
我停在这两个上,因为我意识到我需要为所有空间编写所有运算符重载逻辑,这是一项巨大的工作。我需要以某种方式在一个结构struct Space 中实现运算符重载,并从中派生所有其他结构。注意我不能有任何虚拟方法,因为任何指向vtable 的指针都会增加sizeof(Space) 并且会引发我已经提到的问题。我想我需要模板元编程之类的东西来做到这一点(使用宏是我的最后选择) 或使用CRTP 之类的技术,作为草稿,我认为我的 Space 实现可以是这样的。
using RGB = Space<SpaceComponent<unsigned char,0,255> r,SpaceComponent<unsigned char,0,255> g,SpaceComponent<unsigned char,0,255> b>;
我知道这样写是违法的,但我能有一个结构,它的语法至少和这个差不多吗?提前谢谢。
【问题讨论】:
-
您可能正在寻找
std::tuple -
或者
std::array,如果所有颜色都属于同一类型。 -
@IgorTandetnik 是的,可能是这样,但是迭代一个元组并将一个元素添加到另一个元素的时间效率低于仅添加
a += otherSpace.a。我想我同时需要速度和内存:D -
@IgorTandetnik 它已经过测试)))
-
@max66 将范围从空间组件中拆分出来并定义了特定空间中每个组件的所有范围可能有助于使用
std::arrays 实现这一点
标签: c++ templates colors metaprogramming variadic-templates