问题
How in C++03 get in compile time number of members of chosen struct? I was experimenting with BOOST_FUSION_ADAPT_STRUCT
but I did't get any working example.
I want to generate switch statement in compile time, where there will be one case per each member. So lets say we have struct with 3 members then I want to generate this switch:
switch(val)
{
case 0:
break;
case 1:
break;
case 2:
break;
}
In each statement I will call template function with some parameters. One of this parameters is a member of structure.
How I can do something like this?
回答1:
If you define the struct itself with BOOST_FUSION_DEFINE_STRUCT
, boost will generate your struct in such a way that you can easily do this:
#include <boost/fusion/include/define_struct.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <iostream>
#include <string>
// demo::employee is a Fusion sequence
BOOST_FUSION_DEFINE_STRUCT(
(),
employee,
(std::string, name)
(int, age))
int main() {
employee e{"hey", 5};
int x = boost::fusion::size(e);
std::cerr << x << std::endl;
auto print = [] (auto v) { std::cerr << v << std::endl; };
boost::fusion::for_each(e, print);
return 0;
}
I modified the code above to also iterate over the members of the struct and apply a generic function. It seems like this functionally does the same thing as your hypothetical case statement would.
The reason you cannot pass the "2" this code generates to boost preprocessor macros is because the preprocessor runs first, before the code, you can't feed a number generate at compile time or at runtime into the preprocessor.
This program prints:
2
hey
5
See:
BOOST_FUSION_DEFINE_STRUCT in boost::fusion documentation
size in boost::fusion documentation
Iterating over Boost fusion::vector
回答2:
After long searching, reading and finding this article. I managed to iterate over members from 0 to count - 1 (from that creating switch statement is easy).
#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/fusion/include/define_struct.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/seq/cat.hpp>
struct MyStruct
{
int x;
int y;
};
#define GO(r, data, elem) elem
#define SEQ1 ((int,x))((int,y))
BOOST_FUSION_ADAPT_STRUCT(
MyStruct,
BOOST_PP_SEQ_FOR_EACH(GO, ,SEQ1)
)
#define PRINT(unused, number, data) \
std::cout << number << std::endl;
int main()
{
BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(SEQ1), PRINT, "data")
}
Now BOOST_PP_REPEAT
may create case statements.
来源:https://stackoverflow.com/questions/31712561/compile-time-switch-generation-based-on-number-of-fields-in-structure