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:
union
of your class and an array of char
as big as the classNeedless 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With