Can I static_assert without providing a real template parameter?
template<typename T>
class MyClass
{
......
private:
union u_
{
struct m_
{
int i1;
int i2;
int i3;
} m;
char data[SIZE]; // convenience buffer for serialization/deserialization;
} u;
T container;
......
};
To be able to serialize 开发者_StackOverflow中文版/ deserialize an object of MyClass, I use a union to combine my data fields and use the data buffer to do it wholesale. I want to make sure that data is big enough for the collection of data members in case someone expand them in the future, so I added this static assert.
static_assert(sizeof(MyClass<int>::u_::data) >= sizeof(MyClass<int>::u_::m_));
There are two problems with this approach. First, the compiler complains that the union is not public. Secondly this should hold true for any container type T, so I don't want to be specific, but giving int as a dummy type won't work, but I don't want to introduce another type just for the sake of static assert, is there a way to use a dummy type here?
Is there a more elegant solution?
EDIT: James, thanks for bringing up portability issues. Endianness and alignment are legit concerns, but in my case, serialization/deserialization happens locally, so it's OK.
Is there a more elegant solution?
Why not just reinterpret the struct as an array of char?
struct m_
{
int i1;
int i2;
int i3;
};
// ...
m_ m;
char* data = static_cast<char*>(static_cast<void*>(&m));
Any object can safely be reinterpreted as an array of char. Of course, you still have to worry about alignment, padding, the sizes of your data types, and potential endianness and other representation issues, but presumably you know that since you're writing the serialization implementation.
char data[SIZE];
Instead of this, you can do this:
char data[sizeof(m_)];
It'll always satisfy the condition in this static_assert
:
static_assert(sizeof(MyClass<int>::u_::data) >= sizeof(MyClass<int>::u_::m_));
Since it'll always satisfy, no matter what, you would not even need to write the static_assert
!
To solve the private
issue you can consider putting static_assert
somewhere inside the class, like a constructor or a static method for example.
精彩评论