|
Boost Users : |
Subject: [Boost-users] preprocessor metaprogramming question
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2010-06-20 19:51:39
Hello,
Here's a question for the preprocessor metaprogramming experts out there.
I have some classes that need to have write() methods that look like this:
template <typename output>
bool write(output& out) const
{
return utils::write(out, member_1) &&
utils::write(out, member_2) &&
...
utils::write(out, member_n);
}
where member_1, member_2, ..., member_n are the member variables of the class.
(These write() methods are used as part of a serialization framework).
Since I have quite a few classes that need write() methods that look like this,
and the structure of each write() method is uniform (the only thing that varies
is the names of the class members), I figured that it would be neat to somehow
generate the code for these write() methods.
What I came up with is macros that look like this:
#define MEMBERS1(m1) \
template <typename output> \
bool write(output& out) const \
{ \
return utils::write(out, m1); \
}
#define MEMBERS2(m1, m2) \
template <typename output> \
bool write(output& out) const \
{ \
return utils::write(out, m1) && \
utils::write(out, m2); \
}
// and so on for MEMBERS3, MEMBERS4, etc.
Then, instead of declaring and defining the write() methods explicilty,
I would just call the appropriate MEMBERS# macro in the class definition,
e.g. for a class with 3 members named a, b, and c, I'd write
MEMBERS3(a, b, c) in the class definition.
While this is definitely an improvement over writing the write() methods
explicitly for each class, there are two issues with it:
1) The number of lines of code needed to write the macro definitions
is quadratic in the maximum number of parameters supported.
It would be nice if it could be constant instead.
2) The user of the macros needs to match the macro name to the number
of member variables in the class, and to change the macro name whenever
the number of member variables changes.
I'm wondering if there is a way to improve on this generation scheme
that solves one or both of these issues.
If I were allowed to use C++0x, I could have a variadic macro MEMBERS(...)
and inside it pass the parameters to a variadic template function which
unpacks its parameters and calls utils::write() on each. This would solve
both issues. Unfortunately, however, I am not allowed to use C++0x features,
since our code needs to be able to compile on our servers, which run Ubuntu 8.04,
which runs g++ 4.2, which does not support C++0x features.
So I thought I'd turn to some more preprocessor magic to solve these issues.
I looked at examples in Boost.Preprocessor that generated repetitive code
using preprocessor metaprogramming. However, all the examples there
generated repetitive *code*, whereas what I seem to need is to be able
to generate repetitive *macro definitions*. Is there a way to do that?
If not, can anyone recommend other ways of improving the way I generate
the code for the write() functions?
Thanks in advance,
Nate.
_________________________________________________________________
Learn more ways to connect with your buddies now
http://go.microsoft.com/?linkid=9734388
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net