从另一个

时间:2015-06-08 15:29:38

标签: c++ variadic-templates

我想从class Y生成class X

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的布尔值放在最后以赢得一些记忆,(this is called packing你可以假设成员函数不使用任何可选的,所以生成的代码是正确的,类也可以有尽可能多的选项

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

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

编辑: 这样做的主要目的是通过在末尾添加可选的布尔值来减少第一类的内存(减少填充),由于size的{​​{1}},派生不会这样做将大于derived class

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

1 个答案:

答案 0 :(得分:2)

  

所以,基本上我想在结尾处加上可选的布尔值以赢得一些记忆,

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

使用可变参数模板和按位算法可以解决问题。要聚合成员,您可以使用std::tuple,并使用std::bitset聚合位。从那里,您可以创建一个按值返回optional的访问者。

  

您可以假设成员函数不使用任何可选项,因此生成的代码将是正确的

那里没有会员功能。

你可能会过高估计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 ... }
        {}
    }
};