如何在模板与联合之间进行继承? [英] How to have inheritance between template with union?

查看:27
本文介绍了如何在模板与联合之间进行继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下两个对象.我想知道是否有一种方法可以将 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,gb 以避免混淆,但仍将其存储为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆