如何在编译期间计算C ++ 11中的struct padding?

问题

我有一个gazillion Foo的std :: vector

struct Foo
{
  int   m_i;
  char  m_c;
  char  m_padding[3];   // want to replace this
};

我可以用二进制格式快速地将这部分连续的Foo快速地写入一次。

我的问题是,如果我没有明确地写入m_padding,计算它并自己清除它,valgrind会抱怨未初始化的写入。

是否有可能在C ++ 11中编写模板类,它将在编译期间为我计算该填充?

如果是这样,我可以在我的所有Foo的末尾添加它,并自动初始化/清除它们,而不需要valgrind的投诉。

我可以通过计算sizeof(padding)= sizeof(Foo) - sum(sizeof(parts))来手动完成,但是为这个计算创建某种类是很好的,因为所有的信息在编译时都是可用的。

为了简单起见,假设Foo具有简单的布局(type_traits是一个重要但正切的问题)。 另外,忽略排序问题/跨平台问题。

可能的方法

这并不直接回答我的原始问题,但hvd的建议暗示了一种更简单的方法,似乎适用于我尝试的一些简单测试案例:

template<typename T>
struct BZero
{
  BZero() { std::memset( this, 0, sizeof( T )); }
};

struct Foo : public BZero<Foo>
{
  int   m_i;
  char  m_c;
};

那么,我可以看到两种方式:

  • 使用你的类的一个union和一个像这个类一样大的char数组
  • 使用模板化类和元编程来找出所有填充
  • 毋庸置疑,前者似乎更容易,所以你在这里:

    template <typename T>
    class ZeroedClass {
    public:
        template <typename... Args>
        ZeroedClass(Args&&... args) {
            new (&_.t) T(std::forward<Args>(args)...);
        }
    
        // Need other special members as well
    
        ~ZeroedClass() { _.t.~T(); }
    
        // Accessors
        T& access() { return _.t; }
        T const& get() const { return _.t; }
    
    private:
        union U {
            U() { memset(this, 0, sizeof(T)); }
    
            char buffer[sizeof(T)];
            T t;
        } _;
    }; // class ZeroedClass
    

    不知道我是否理解得好,这又如何:

    struct FooBase {
        int i;
        char c;
    };
    
    template<typename T, size_t total>
    struct padded : public T {
        char pad[total-sizeof(T)];
    };
    
    typedef padded<FooBase, 8> Foo;
    
    链接地址: http://www.djcxy.com/p/19149.html

    上一篇: How to calculate struct padding in c++11 during compile time?

    下一篇: Set Cover or Hitting Set; Numpy, Least element combinations to make up full set