下一个应该与C++ 11的工作。
有点棘手的确,它基于的@SamVarshavchik评论:
#include<cstddef>
#include<functional>
template<std::size_t> struct Int { int i; };
template<std::size_t> struct Char { char c; };
template<std::size_t> struct Bool { bool c; };
template<typename, template<std::size_t> class...>
struct Base;
template<template<std::size_t> class... T, std::size_t... I>
struct Base<std::index_sequence<I...>, T...>: T<I>... {};
template<template<std::size_t> class... T>
struct Check final: Base<std::make_index_sequence<sizeof...(T)>, T...> {};
class A final {
bool _attribute1;
bool _attribute2;
private:
char _attribute3;
// int _attribute4;
};
void serialize(const A &) {
static_assert(sizeof(A) == sizeof(Check<Bool, Bool, Char>), "!");
// do whatever you want here...
}
int main() {
serialize(A{});
}
的基本思想是列出所有类型的数据成员和定义一个新的类型,从他们一个mixin。那么这是一个把static_assert
放在正确的地方的问题。
请注意,也会考虑私人数据成员。
存在一些可能会破坏它的角落案例,但也许它可以为您的真实代码工作。
作为一个侧面说明,它可以进一步简化,如果C++ 14是一个选项:
#include<cstddef>
template<typename... T>
constexpr std::size_t size() {
std::size_t s = 0;
std::size_t _[] = { s += sizeof(T)... };
(void)_;
return s;
}
class A final {
bool _attribute1;
bool _attribute2;
private:
char _attribute3;
// int _attribute4;
};
void serialize(const A &) {
static_assert(sizeof(A) == size<bool, bool, char>(), "!");
// ...
}
int main() {
serialize(A{});
}
我不认为这是可能的。 –
我能想到的唯一的事情是在sizeof(A)上的某个静态断言。因此,如果有东西被添加,某些东西将无法编译,直到新的类成员被序列化并且相应地调整静态断言。 –
您可以将自定义脚本或程序添加到您的生成文件或IDE预生成步骤中,以检查该类的所有成员是否都包含在该函数中。 – wally