Reputation: 40108
I need to make sure a template struct is exactly the size of its members. static_assert
seems to be the tool of choice here. However, I cannot use a static_assert
inside the struct itself, because the size is not yet known there. Here is what I would like to have:
template<typename T1,typename T2>
struct foo {
T1 v1;
T2 v2;
// Doesn't compile, invalid application of sizeof to incomplete type
static_assert(sizeof(foo<T1,T2>)==sizeof(T1)+sizeof(T2),"Struct size invalid");
};
This doesn't work. So how to do it? I don't want to burden people that instantiate the template to check themselves in each instantiation. The check should be fully automatic whenever the struct is instantiated.
Upvotes: 20
Views: 2478
Reputation: 69902
Place the static assertion in a member function.
template<typename T1,typename T2>
struct foo {
T1 v1;
T2 v2;
static auto assertion()
{
static_assert(sizeof(foo<T1,T2>)==sizeof(T1)+sizeof(T2),"Struct size invalid");
}
};
This works because the contents of member functions are not compiled until the class has a complete definition.
There is no need to call the function.
Upvotes: 7
Reputation: 217970
You may add a layer:
template<typename T1,typename T2>
struct bar {
T1 v1;
T2 v2;
};
template<typename T1,typename T2>
struct foo : bar<T1, T2> {
static_assert(sizeof(bar<T1, T2>) == sizeof(T1) + sizeof(T2), "Struct size invalid");
};
Upvotes: 10
Reputation: 275760
Rename foo
to foo_t
.
template<class A, class B>
struct foo_helper {
using type=foo_t<A,B>;
static_assert(sizeof(A)+sizeof(B) == sizeof(type), "ouch");
};
template<class A, class B>
using foo=typename foo_helper<A,B>::type;
Note that using foo
instead of foo_t
blocks deduction in some cases, so this technique is not perfect.
Upvotes: 15