Poniżej jeden powinien pracować z C++ 11.
trochę skomplikowane rzeczywiście, jest ona oparta na komentarzu @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{});
}
Podstawową ideą jest, aby wymienić wszystkie rodzaje członków danych i zdefiniować nowy typ z nich z wstawek. To kwestia umieszczenia static_assert
we właściwym miejscu.
Należy pamiętać, że prywatni członkowie danych są również brani pod uwagę.
Istnieje kilka przypadków narożnych, które mogą go złamać, ale może to zadziałać w przypadku rzeczywistego kodu.
Na marginesie, to może być dalej uproszczone, jeśli C++ 14 jest opcją:
#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{});
}
Nie sądzę, że to możliwe. –
Jedyne, co mogłem wymyślić, to statyczne stwierdzenie gdzieś na sizeof (A). W związku z tym, jeśli coś zostanie dodane, coś nie uda się skompilować, dopóki nowy członek klasy nie zostanie zserializowany, a asercja statyczna zostanie odpowiednio dostosowana. –
Możesz dodać niestandardowy skrypt lub program do swoich makefile lub wstępnych kroków IDE, aby sprawdzić, czy wszyscy członkowie klasy są włączeni do tej funkcji. – wally