繁体   English   中英

可变的类/结构结构? (不是模板,不是联合?)

[英]Variable class/struct structure? (Not template & not union?)

我试过工会...

struct foo
{
    union
    {
        struct // 2 bytes
        {
            char var0_1;
        };
        struct // 5 bytes
        {
            char var1_1;
            int var1_2;
        };
    };
};

问题:联合会按我的意愿行事,只是它们将始终占用最大数据类型的大小。 在我的情况下,我需要对foo进行一些初始化,以便让我告诉它选择两者中的哪种结构(如果合法),如下所示。

所以之后,我尝试了类模板重载...

template <bool B>
class foo { }

template <>
class foo<true>
{
    char var1;
}

template <>
class foo<false>
{
    char var0;
    int var1;
}

问题:我对模板以及可以在char和int上使用相同的变量名感到非常满意,但问题是语法。 因为这些类是在编译时创建的,所以模板布尔值变量必须是硬编码常量,但是在我的情况下,布尔值需要在运行时由用户定义。

因此,我需要两个“世界”中的某个。 我如何才能实现自己的目标?

!!注意:foo类/结构将在以后被继承,因此,正如已经提到的,foo的大小至关重要。

EDIT#1 ::应用程序:

基本上,这将用于读取/写入(使用指针作为接口)特定的数据缓冲区,并且还允许我创建(类/结构的新实例)相同的数据缓冲区。 您在上面看到的变量指定了长度。 如果是较小的数据缓冲区,则长度以char / byte写入。 如果它是更大的数据缓冲区,则第一个char / byte作为标志为null,而int则指定长度。 在长度之后,很明显,实际数据随之出现,因此为什么要继承。 班级规模至关重要。 我也要吃蛋糕。

抽象层。

struct my_buffer_view{
  std::size_t size()const{
    if (!m_ptr)return 0;
    if (*m_ptr)return *m_ptr;
    return *reinterpret_cast<std::uint32_t const*>(m_ptr+1);
  }
  std::uint8_t const* data() const{
    if(!m_ptr)return nullptr;
    if(*m_ptr)return m_ptr+1;
    return m_ptr+5;
  }
  std::uint8_t const* begin()const{return data();}
  std::uint8_t const* end()const{return data()+size();}
  my_buffer_view(std::uint_t const*ptr=nullptr):m_ptr(ptr){}
  my_buffer_view(my_buffer_view const&)=default;
  my_buffer_view& operator=(my_buffer_view const&)=default;
private:
  std::uint8_t const* m_ptr=0;
};

任何地方都没有大小可变的数据。 我可能已经为size etx使用了一个联合:

  struct header{
    std::uint8_t short_len;
    union {
      struct{
        std::uint32_t long_len;
        std::uint8_t long_buf[1];
      }
      struct {
        std::short_buf[1];
      }
    } body;
  };

但是我只是做指针运算。

将这样的缓冲区写入字节流完全是另一个问题。

您的解决方案没有道理。 考虑一下您的解决方案:您可以定义两个独立的类:fooTrue和fooFalse,其对应成员的结果完全相同。

可能您正在寻找其他解决方案作为继承。 例如,您的fooTrue是baseFoo,而fooFalse则是namedFoo,并且前一个作为基础,并使用另一个int成员对其进行了扩展。

在这种情况下,您可以将多态作为在运行时工作的方法。

你不能吃蛋糕也不能吃。

模板的要点是专业化发生在编译时。 在运行时,类的大小是固定的(尽管以实现定义的方式)。

如果要在运行时进行选择,则不能使用在编译时确定大小的机制。 您将需要一个能够同时满足两种可能需求的机制。 实际上,这意味着您的基类将需要足够大以包含所有必需的成员-这实际上是基于联合的解决方案所发生的事情。

参考您的“!注意”。 您所做的工作属于过早的优化。 您正在尝试优化基类的大小,而没有任何证据(例如内存使用情况的度量)来证明大小差异实际上对您的应用程序很重要(例如,这会导致应用程序耗尽可用内存)。 仅凭某种东西将成为许多其他类的基础这一事实本身不足以担心其大小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM