So, according to this answer, C++ doesn't support variadic macros, and the C++ standard doesn't mention variadic macros anywhere. I know that C99 introduced variadic macros with __VA_ARGS__
, and certain C++ compilers (like GCC) even provide extensions to allow this in C++, but the fact remains that variadic macros simply aren't part of standard C++.
Now, there's a feature in Boost.Fusion where you can bind a Fusion sequence to an arbitrary class or struct using the BOOST_FUSION_ADAPT_STRUCT
macro. This allows you to use your class or struct as if it was a Fusion sequence.
Here is an example of how this is used (taken from the Boost docs):
namespace demo
{
struct employee
{
std::string name;
int age;
};
}
// demo::employee is now a Fusion sequence
BOOST_FUSION_ADAPT_STRUCT(
demo::employee,
(std::string, name)
(int, age))
Now, how is this code possible without variadic macros? The BOOST_FUSION_ADAPT_STRUCT
macro seems to take an arbitrary number of argumen开发者_开发百科ts, since presumably it can work with any arbitrary user-defined class or struct.
I know that Boost is famous for bending C++ in interesting ways, but this seems outright impossible without compiler support. So what sort of wizardry is Boost.Fusion doing to pull this off?
PS: Yes, I know Boost is open source. The first thing I did was to look at the source code. It seems to be using the Boost Preprocessor library to somehow concatenate macros. But I don't understand how this can work for any arbitrary number of arguments, and the source code is a very dense collection of preprocessor code which is very difficult to understand.
BOOST_FUSION_ADAPT_STRUCT(
demo::employee,
(std::string, name)
(int, age))
This is a single macro which takes two arguments: Argument 1: demo::employee Argument 2: (std::string, name)(int, age)
Argument 2 is concatenated with a string to form another macro invocation which also takes 2 parameters:
BOOST_FUSION_SOME_INTERNAL_MACRO(std::string, name)
BOOST_FUSION_SOME_INTERNAL_MACRO(int, age)
精彩评论