Previously I had a boost-focused answer that I wasn't able to test. Here's something more comprehensible using a combination of template meta-programming and macros:
#include <iostream>
// Build a base template for the save Implementation
template <typename... ARG_TYPES>
struct save_impl;
// Create a DoSerialize function that will recursively serialize all objects.
template <typename Archive, typename FIRST_TYPE, typename... OTHER_TYPES>
struct save_impl<Archive, FIRST_TYPE, OTHER_TYPES...> {
static void DoSerialize(Archive& arch, FIRST_TYPE & arg1, OTHER_TYPES&... others) {
// Instead of printing in the next line, do: arch & BOOST_SERIALIZATION_NVP(a);
std::cout << arch << arg1 << std::endl;
save_impl<Archive, OTHER_TYPES...>::DoSerialize(arch, others...);
}
};
// Base case to end recursive call of struct-based DoSerialize
template <typename Archive>
struct save_impl<Archive> {
static void DoSerialize(Archive& arch) { ; }
};
// Create a DoSerialize function that will call struct-based implementation.
template <typename Archive, typename... ARG_TYPES>
void DoSerialize(Archive & arch, ARG_TYPES&... args) {
save_impl<Archive, ARG_TYPES...>::DoSerialize(arch, args...);
}
// Create the desired macro to add the serialize function to a class.
#define SET_SAVED_MEMBERS(...) \
template<typename Archive> \
void serialize(Archive& arch) { \
DoSerialize(arch, __VA_ARGS__); \
}
Currently I have it just printing so I could test it (but indicate above the line you would need to change). Here is a test using your apple example:
class apple {
public:
int a;
bool isTasty;
float unimportantData;
SET_SAVED_MEMBERS(a, isTasty);
};
int main() {
apple a = {7, false, 2.34};
a.isTasty=true;
a.serialize("Archive: ");
}
Note that I'm sending in a string instead of an archive object -- that works fine with the fact that it's currently using print.
BOOST_SERIALIZATION_NVPis a c preprocessor macro, you have no chance with using template parms, simply because the evaluation of macros will be done before templates are expanded. But I also did not understand what your problem is. Do you only want to write less code by hand?::boost::serialization::make_nvp("a", a);<typename ... T> void X(T...a )have the name a which is not helpful in this use case.