根据结构中的字段数编译时间开关生成
Compile time switch generation based on number of fields in structure
C++03如何在编译时获取所选结构的成员数?我正在试验 BOOST_FUSION_ADAPT_STRUCT
但我没有得到任何有效的例子。
我想在编译时生成 switch 语句,每个成员都有一个 case。所以假设我们有 3 个成员的结构然后我想生成这个开关:
switch(val)
{
case 0:
break;
case 1:
break;
case 2:
break;
}
在每个语句中,我都会调用带有一些参数的模板函数。此参数之一是结构成员。
我怎么能做这样的事情?
如果您使用 BOOST_FUSION_DEFINE_STRUCT
定义结构本身,boost 将以您可以轻松执行此操作的方式生成您的结构:
#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;
}
我修改了上面的代码以迭代结构的成员并应用通用函数。看起来这在功能上与您假设的案例陈述所做的相同。
您不能将此代码生成的“2”传递给预处理器宏的原因是预处理器首先运行,在代码之前,您不能将编译时或运行时生成的数字输入预处理器。
这个程序打印:
2
hey
5
参见:
Iterating over Boost fusion::vector
经过长时间的搜索、阅读和发现 this article。我设法遍历从 0 到 count - 1 的成员(创建 switch 语句很容易)。
#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")
}
现在 BOOST_PP_REPEAT
可以创建 case 语句。
C++03如何在编译时获取所选结构的成员数?我正在试验 BOOST_FUSION_ADAPT_STRUCT
但我没有得到任何有效的例子。
我想在编译时生成 switch 语句,每个成员都有一个 case。所以假设我们有 3 个成员的结构然后我想生成这个开关:
switch(val)
{
case 0:
break;
case 1:
break;
case 2:
break;
}
在每个语句中,我都会调用带有一些参数的模板函数。此参数之一是结构成员。
我怎么能做这样的事情?
如果您使用 BOOST_FUSION_DEFINE_STRUCT
定义结构本身,boost 将以您可以轻松执行此操作的方式生成您的结构:
#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;
}
我修改了上面的代码以迭代结构的成员并应用通用函数。看起来这在功能上与您假设的案例陈述所做的相同。
您不能将此代码生成的“2”传递给预处理器宏的原因是预处理器首先运行,在代码之前,您不能将编译时或运行时生成的数字输入预处理器。
这个程序打印:
2
hey
5
参见:
Iterating over Boost fusion::vector
经过长时间的搜索、阅读和发现 this article。我设法遍历从 0 到 count - 1 的成员(创建 switch 语句很容易)。
#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")
}
现在 BOOST_PP_REPEAT
可以创建 case 语句。