C++ 两个并集之间的循环强制转换运算符

C++ 两个并集之间的循环强制转换运算符,c++,struct,casting,operators,C++,Struct,Casting,Operators,我有以下两个工会: union rgb_color { struct { float red; float green; float blue; }; float raw[3]; }; union hsv_color { struct { float hue; float saturation; float value; }; float raw[3]; } 我想将操作符hsv\u color()添加到rgb\u col

我有以下两个工会:

union rgb_color
{
  struct {
    float red;
    float green;
    float blue;
  };
  float raw[3];
};

union hsv_color
{
  struct {
    float hue;
    float saturation;
    float value;
  };
  float raw[3];
}
我想将
操作符hsv\u color()
添加到
rgb\u color
union
,并将
操作符rgb\u color()
添加到
hsv\u color
union
。有办法吗?如果我向前声明hsv\U颜色,编译器将抛出以下错误:

error: return type 'union hsv_color' is incomplete
我越是尝试实现这一点,我就越觉得应该创建两个函数来进行转换,而不是使用隐式强制转换操作符。
不过,我想知道这是否可行。有什么建议吗?

我建议使用下面的代码,但您的基本假设是,由3个浮点组成的结构将占用与由3个浮点组成的数组完全相同的内存,这可能是错误的。存在结构构件对齐。您需要使用一些“pragma-pack”指令。 例如阅读

struct hsv_color;

struct rgb_color
{
  union
  {
      struct 
      {
        float red;
        float green;
        float blue;
      }rgb;
      float raw[3];
  };
  operator hsv_color();
 };

struct hsv_color
{
    union
    {
      struct 
      {
        float hue;
        float saturation;
        float value;
      } hsv;
      float raw[3];
    };

    operator rgb_color();
};

rgb_color::operator hsv_color()
{
    hsv_color ret;

    // convert 'this' to hsv_color
    ret.hsv.hue = 0;//todo: perform appropriate calculation here
    ret.hsv.saturation = 0;//todo: perform appropriate calculation here
    ret.hsv.value = 0;//todo: perform appropriate calculation here

    return ret;
}

hsv_color::operator rgb_color ()
{
    rgb_color ret;

    // convert 'this' to rgb_color
    ret.rgb.red = 0;//todo: perform appropriate calculation here
    ret.rgb.green = 0;//todo: perform appropriate calculation here
    ret.rgb.blue = 0;//todo: perform appropriate calculation here

    return ret;
}

我建议使用下面的代码,但您的基本假设是3个浮点数的结构将占用与3个浮点数的数组完全相同的内存,这可能是错误的。存在结构构件对齐。您需要使用一些“pragma-pack”指令。 例如阅读

struct hsv_color;

struct rgb_color
{
  union
  {
      struct 
      {
        float red;
        float green;
        float blue;
      }rgb;
      float raw[3];
  };
  operator hsv_color();
 };

struct hsv_color
{
    union
    {
      struct 
      {
        float hue;
        float saturation;
        float value;
      } hsv;
      float raw[3];
    };

    operator rgb_color();
};

rgb_color::operator hsv_color()
{
    hsv_color ret;

    // convert 'this' to hsv_color
    ret.hsv.hue = 0;//todo: perform appropriate calculation here
    ret.hsv.saturation = 0;//todo: perform appropriate calculation here
    ret.hsv.value = 0;//todo: perform appropriate calculation here

    return ret;
}

hsv_color::operator rgb_color ()
{
    rgb_color ret;

    // convert 'this' to rgb_color
    ret.rgb.red = 0;//todo: perform appropriate calculation here
    ret.rgb.green = 0;//todo: perform appropriate calculation here
    ret.rgb.blue = 0;//todo: perform appropriate calculation here

    return ret;
}

我会避免类型双关联合,因为它在严格的别名规则下变成UB

我认为您涉及一个数组,因为您需要将该数组传递给API,例如opengl

在这种情况下,我将简单地使用数组并提供访问器来访问r、g、b、h、s和v的语义

您可以为必要的转换构造函数提供转发声明:

// forward declare
struct hsv_color;

struct rgb_color
{
  rgb_color(float r, float g, float b)
    : raw { r, g, b }
  {}

  // forward declare
  rgb_color(hsv_color);

  float& r() { return raw[0]; }
  const float& r() const { return raw[0]; }
  float& g() { return raw[1]; }
  const float& g() const { return raw[1]; }
  float& b() { return raw[2]; }
  const float& b() const { return raw[2]; }

  const float* data() const  { return raw; }
  float* data()  { return raw; }

  private:
  float raw[3];
};

struct hsv_color
{
  hsv_color(float h, float s, float v)
   : raw { h, s, v }
  {}

  hsv_color(rgb_color rgb) { /*conversion here*/ }

  // more accessors here

  float raw[3];
};

// define

rgb_color::rgb_color(hsv_color hsv) { /* implement here */ }

我会避免类型双关联合,因为它在严格的别名规则下变成UB

我认为您涉及一个数组,因为您需要将该数组传递给API,例如opengl

在这种情况下,我将简单地使用数组并提供访问器来访问r、g、b、h、s和v的语义

您可以为必要的转换构造函数提供转发声明:

// forward declare
struct hsv_color;

struct rgb_color
{
  rgb_color(float r, float g, float b)
    : raw { r, g, b }
  {}

  // forward declare
  rgb_color(hsv_color);

  float& r() { return raw[0]; }
  const float& r() const { return raw[0]; }
  float& g() { return raw[1]; }
  const float& g() const { return raw[1]; }
  float& b() { return raw[2]; }
  const float& b() const { return raw[2]; }

  const float* data() const  { return raw; }
  float* data()  { return raw; }

  private:
  float raw[3];
};

struct hsv_color
{
  hsv_color(float h, float s, float v)
   : raw { h, s, v }
  {}

  hsv_color(rgb_color rgb) { /*conversion here*/ }

  // more accessors here

  float raw[3];
};

// define

rgb_color::rgb_color(hsv_color hsv) { /* implement here */ }

我希望您不要使用这些联合输入puning:例如,写入
raw
,然后读取
hue
,反之亦然UB@Revolver_Ocelot:如果你所说的UB是指未定义的行为,那么该死的,我不知道!是C++还是C?这是工会如何工作的,如果你需要代码>原始<代码> >代码>色相<代码>,也许它不应该是第一个联合。place@xx77aBs我希望你不要和这些工会打交道:例如,写入
raw
,然后从
hue
读取,反之亦然UB@Revolver_Ocelot:如果你所说的UB是指未定义的行为,那么该死的,我不知道!是C++还是C?这是工会如何工作的,如果你需要代码>原始<代码> >代码>色相<代码>,也许它不应该是第一个联合。place@xx77aBs