从另一个生成 C++ class

Generate a C++ class from an other one

我想从 class X 生成 class Y :

class X{

  T e;
  optional<T1> e1;
  optional<T2> e2;
  optional<T3> e3;
  T4 e4;

  // Member functions
  ...
};

class Y{ 
  T  e;
  T1 e1;
  T2 e2;
  T3 e3;
  T4 e4;
  bool b1;
  bool b2;
  bool b3;

  // Member functions
  ...
}

所以,基本上我想放入 optional at the end to win some memory, (this is called packing) 的布尔值 你可以假设成员函数不使用任何可选的,所以生成的代码是正确的,class 也可以有尽可能多的可选值

我知道 C++ 中没有 class 反射,但是使用 Variadic 模板,我们似乎可以做一些很棒的事情。

我一直在考虑使用它们来解决这个问题,但我找不到任何解决方案。我以为其他人可能已经尝试过类似的东西。

编辑: 这样做的主要目标是通过将可选的布尔值放在末尾(减少填充)来减少第一个 class 的内存,推导不会这样做,因为 size derived class 会大于 base class

代码可以通过将 class X 作为模板传递给生成器 ClassGenerator<X> 来生成,或者生成器可以采用更多参数,例如 ClassGenerator<X, T1, T2, T3>

So, basically I want to put the booleans of optional at the end to win some memory,

回收内存的最佳方法是将它们声明为位域,或者手动执行等效的按位运算。

这个问题可以通过使用可变参数模板和按位运算来解决。要聚合成员,您可以使用 std::tuple,聚合位使用 std::bitset。从那里,您可以创建一个 returns 按值 optional 的访问器。

You can assume that the member functions doesn't use any optional, so the generated code would be correct

那里没有成员函数。

您可能高估了 C++ 为您提供的类型转换自由度。例如,您不能将 X* 转换为 Y*。不是由一个长镜头。 (至少,如果您使用 Y* 结果则不会。)


真的,困难的部分是您不再拥有 optional,您需要重新发明它。所以你需要某种形式的工会,但单独的工会不知道如何移动或摧毁自己,因为他们需要那一点。所以你不能把它们放在 tuple 里面,所以你也需要重新发明 tuple

template< typename t >
union storage {
    t value;

    storage() {} // uninitialized
    storage( t in ) : value( std::move( in ) ) {}
    // Impossible to define the copy/move constructor.

    ~ storage() // Impossible to define. Destroy value or not?
};

template< typename ... elem >
class optional_tuple {
    std::tuple< storage< elem > ... > e
    std::bitset< sizeof ... (elem) > b;

    optional_tuple( std::optional< elem > ... v )
        : e{ std::move( v ) ... }
        , b{ (bool) v ... }
        {}
    }
};