草庐IT

C++(以某种方式)将结构限制为父 union 大小

coder 2024-02-03 原文

我正在尝试创建一个可变大小的颜色类 - 给定一个模板确定的值数组,我想为数组中的每个值创建命名别名,即:

template<int C = 3, typename T = unsigned char>
class Color {
public:
  union {
    T v[C];
    struct {
      T r, g, b, a;
    };
  };
};

但是,如果我尝试对 C=3 使用相同的类, union 要求大小为 4 个字节(“a”成员)。或者,使用 a 的数学表达的位域大小(名为 a 的结构,匿名 T 成员,大小在 C>3 时计算为 1),编译器发出一个许可警告(不可抑制,根据 In gcc, how to mute the -fpermissive warning? ),这是不适合的更大规模的 API。

我将如何允许单个类处理不同数量的变量,同时保留每个变量的名称并且不实现递归包含宏魔术(尝试过,不应该)。提前致谢!

编辑:为了澄清问题,以下任何一个的答案都将解决这个问题:

  • 抑制 GCC 的 -fpermissive 错误(#pragma diagnostic ignored 不适用于 permissive)
  • 设置 union 或子结构的最大大小不超过 C 字节
  • 对于未被 C 字节覆盖的成员,允许位域长度为 0(GCC 允许位域长度的数学表达式,例如 (C-3 > 0)?8:0; )
  • 通过其他方式(即虚构的 static_if() )禁用未被 C 字节覆盖的成员

最佳答案

您可以针对 C 的不同情况对结构进行专门化:

template <int C = 3, typename T = unsigned char> union Color;

template <typename T>
union Color<3,T> {
  T v[3];
  struct {
    T r,g,b;
  };
};

template <typename T>
union Color<4,T> {
  T v[4];
  struct {
    T r,g,b,a;
  };
};

请注意,匿名结构是非标准的。

如果可以使用成员函数,我认为那将是一个更好的方法:

template <int C,typename T>
class Color {
  public:
    using Values = T[C];

    Values &v() { return v_; }

    const Values &v() const { return v_; }

    T& r() { return v_[0]; }
    T& g() { return v_[1]; }
    T& b() { return v_[2]; }

    template <int C2 = C,
      typename = typename std::enable_if<(C2>3)>::type>
    T& a()
    {
      return v_[3];
    }

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

    template <int C2 = C,
      typename = typename std::enable_if<(C2>3)>::type>
    const T& a() const
    {
      return v_[3];
    }

  private:
    Values v_;
};

然后你可以像这样使用它:

int main()
{
  Color<3,int> c3;
  Color<4,int> c4;

  c3.v()[0] = 1;
  c3.v()[1] = 2;
  c3.v()[2] = 3;

  std::cout <<
    c3.r() << "," <<
    c3.g() <<"," <<
    c3.b() << "\n";

  c4.v()[0] = 1;
  c4.v()[1] = 2;
  c4.v()[2] = 3;
  c4.v()[3] = 4;

  std::cout <<
    c4.r() << "," <<
    c4.g() << "," <<
    c4.b() << "," <<
    c4.a() << "\n";
}

关于C++(以某种方式)将结构限制为父 union 大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28950368/

有关C++(以某种方式)将结构限制为父 union 大小的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  6. ruby-on-rails - 正确的 Rails 2.1 做事方式 - 2

    question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参

  7. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  10. HBase Region 简介和建议数量&大小 - 2

    Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile

随机推荐