How to calculate struct padding in c++11 during compile time?

PROBLEM

I have a std::vector of a gazillion Foo's

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

I can fwrite this chunk of contiguous Foo's quickly in binary form all in one shot.

My problem is, if I don't put in that m_padding explicitly, calculate it, and clear it myself, valgrind will complain about uninitialized writes.

QUESTION

Is it possible to write a template class in C++11 which will calculate that padding for me during compile time?

If so, I could just add it at the end of all my Foo's and auto-initialize/clear them without complaint from valgrind.

I can do it manually by calculating sizeof( padding ) = sizeof( Foo ) - sum( sizeof( parts )), but it would be nice to create some kind of class for this calculation since all information is available at compile-time.

For simplicity, assume that Foo has trivial layout (type_traits is an important, but tangent issue). Also, ignore ordering issues/cross-platform issues.

Possible Approach

This doesn't answer my original question directly, but hvd's suggestion implies a simpler approach that seems to work for some simple test cases that I tried:

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

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

Well, I can see two ways:

  • Use a union of your class and an array of char as big as the class
  • Use a templated class and meta-programming to figure out all the paddings
  • Needless to say the former seems much easier, so here you go:

    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/19150.html

    上一篇: 矩阵的总和之间的差异最小

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