gpt4 book ai didi

c++ - 像数组一样访问成员?

转载 作者:搜寻专家 更新时间:2023-10-31 01:38:59 32 4
gpt4 key购买 nike

由于阅读了很多警告不要像这样使用 union :

union rgba
{
struct
{
uint8_t r, g, b, a;
} components;
uint8_t index[4];
uint32_t value;
};

因为这是未定义的行为,所以我决定像这样保持简单:

struct rgba
{
uint8_t r, g, b, a;
};

但有时我确实需要访问 rgba在使用索引的循环中,否则我必须分别为每个组件复制相当长的代码。

所以我想到了这个:

struct rgba
{
u8 r, g, b, a;

constexpr u8& operator[](size_t x)
{
return const_cast<u8*>(&r)[x];
}
};

这依赖于以下假设:rgba 以线性方式放置在内存,中间没有隐藏的样板,编译器保留变量顺序。

有了这个,我可以像我想要的那样访问组件:

rgba c;
for (int i = 0; i < 3; i++)
c[i] = i ^ (i + 7);
c.a = 0xFF;
  1. 因为我做了相当大的假设,所以我很确定这比使用 union 进行类型双关更未定义的行为。我说得对吗?
  2. 我还能如何实现类似的设计?
    1. 我想尽可能避免编写 c.r() = 5,因为它看起来很有趣。
    2. c.components[RED] 等访问器使用宏,我想避免使用宏。
    3. 如果考虑到访问此类枚举所需的 namespace ,用枚举替换第 2 点中的宏看起来会很丑陋。想象一下 c.components[Image::Channels::Red]

最佳答案

标准给出了关于问题 1 的答案:

9.2/15: Nonstatic data members of a class with the same access control are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified. Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions and virtual base classes.

问题 2 的答案有多种选择。如果您喜欢数组表示法:

  • 为什么不使用 switch() 来安全地将引用返回到正确的元素。
  • 或者更好,为什么不用真正的数组替换您的成员?

第一个看起来像:

struct rgba2
{
uint8_t r, g, b, a;
constexpr uint8_t& operator[](size_t x)
{
assert(x>=0 && x<4);
switch (x){
case 0: return r;
case 1: return g;
case 2: return b;
case 3: return a;
//default: throw(1); // not possible with constexpr
}
}
};

第二个:

struct rgba3
{
enum ergb { red, green, blue, alpha};
uint8_t c[alpha+1];
constexpr uint8_t& operator[](ergb x)
{
assert(x>=0 && x<4);
return c[x];
}
};

live demo

关于c++ - 像数组一样访问成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32023374/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com