我需要确保模板结构与其成员的大小完全相同。 static_assert
似乎是这里的首选工具。但是,我不能在结构本身内部使用static_assert
,因为那里的大小还不知道。这就是我想要的:
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");
};
这不起作用。那怎么办呢?我不想让实例化模板的人负担,以便在每个实例中检查自己。每当实例化结构时,检查应该是完全自动的。
答案 0 :(得分:15)
将foo
重命名为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;
请注意,在某些情况下,使用foo
代替foo_t
会阻止扣除,因此这项技术并不完美。
答案 1 :(得分:9)
您可以添加图层:
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");
};
答案 2 :(得分:5)
将静态断言放在成员函数中。
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");
}
};
这是有效的,因为在类具有完整的定义之前,不会编译成员函数的内容。
无需调用该功能。