变量类/结构结构? (不是模板而不是联盟?)

时间:2016-07-25 19:19:22

标签: c++ templates struct

我试过工会......

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

问题:工会做我想做的事,除了它们总是采用最大数据类型的大小。在我的情况下,我需要struct foo进行一些初始化,允许我告诉它选择哪个结构(如果这是合法的),如下所示。

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

template <bool B>
class foo { }

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

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

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

所以我需要两个“世界”的东西。我怎样才能实现我想要做的事情?

!!注意:foo类/ struct稍后会被继承,因此如前所述,foo的大小至关重要。

EDIT#1 :: 应用程序:

基本上这将用于读/写(使用指针作为接口)特定的数据缓冲区,并且还允许我创建(类/ struct的新实例)相同的数据缓冲区。您在上面看到的变量指定长度。如果它是一个较小的数据缓冲区,则长度以char / byte写入。如果它是一个更大的数据缓冲区,则第一个char / byte为null作为标志,而int指定长度。在长度之后,显然实际数据如下,因此为什么继承。课程的大小是最重要的。我需要吃蛋糕然后吃。

3 个答案:

答案 0 :(得分:1)

一个抽象层。

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;
  };

但我只是做了指针运算。

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

答案 1 :(得分:0)

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

或许,您正在寻找一种不同的解决方案作为继承。例如,你的fooTrue是baseFoo,你的fooFalse是derivedFoo,前一个是base,并用另一个int成员扩展它。

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

答案 2 :(得分:0)

你也不能吃蛋糕。

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

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

参考您的&#34; !!注意&#34;。你所做的就是过早优化。您正在尝试优化基类的大小而没有任何证据(例如,内存使用量的测量),大小差异对于您的应用程序实际上是重要的(例如,它会导致应用程序耗尽可用内存)。事情是某些东西将成为许多其他类的基础,这本身就不足以担心它的大小。