gexicide
gexicide

Reputation: 40108

Static assertions about the size of a template struct

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

Answers (3)

Richard Hodges
Richard Hodges

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

Jarod42
Jarod42

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

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

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

Related Questions