ATL macros create arrays that are then used in one or more functions. Since your data is heterogeneous, maybe the exact same approach might not be possible, so I leave you with an approximation:
1 2 3 4 5 6 7 8 9 10 11 12
#define BEGIN_INPUTOUTPUT() virtual void serialize() const {
#define END_INPUTOUTPUT() }
//And this one would be repeated once per variable
#define INPUTOUTPUT_ENTRY(type, name) outValue(type, name)
//And you would use them like this:
BEGIN_INPUTOUTPUT()
INPUTOUTPUT_ENTRY(int, field1);
INPUTOUTPUT_ENTRY(std::string, field2);
INPUTOUTPUT_ENTRY(std::vector<double>, field3);
END_INPUTOUTPUT()
The trouble of that approach is, the user still have to specify the idx twice, one in the serialize and one in the deserialize, that's exactly what I wan to avoid ...
True, but imagine this: If you can somehow create an array of the different objects (maybe by using a polymorphic base), then you can have the macros declare an array and then the functions can refer to this array.
If this doesn't suit your needs, then go with helios' approach.