我正在尝试编写一个在运行时动态加载其扩展的应用程序.我使用Boost预处理器库来编写预处理器函数,给定一个名称列表,为每个名称声明一个类(并使所有这些类成为某些AbstractPlugin类的子类),然后声明包含这些类的Boost MPL序列.然后我编写了一个类,它尝试指向AbstractPlugin,如果它可以转换为该MPL序列中的任何类型.这里的问题是我的预处理器功能需要我想要创建和加载的所有扩展的完整列表.是否有一些技术可以让我在一个单独的文件中注册每个扩展名?
更新:
我相信,我对情况的解释太模糊了,所以我决定让它更具体.
我想定义一个扩展类型的集合.对于每种扩展类型,可以有任意数量的扩展名.在运行期间,程序加载外部库,解析入口点函数,调用它,结果得到一个指针.然后它尝试将该指针强制转换为所有已注册的扩展类型(使用dynamic_cast,因此扩展类型的类都从某些多态基类继承).如果对某个扩展类型的强制转换成功,则在对该扩展类型的特殊处理程序的调用中使用已转换的指针.
扩展类型的数量在编译时是已知的(显然,扩展的数量是无限的).使用我的aproach,loader类使用这些知识来检查是否存在每个扩展类型的处理程序(如果没有,程序不编译).另外,我的aproach不强制扩展类型的类知道有关加载器的任何信息(因此很容易修改加载器).但是如果每个扩展类型都注册自己会更方便.
如何使用boost :: preprocessor解压缩一对对?
例如,我有一个如下序列(逗号之间无关紧要)
(int,x)(double,y)(float,z) or
(int,x),(double,y),(float,z) or
((int)(x))((double)(y))((float)(z))
Run Code Online (Sandbox Code Playgroud)
并希望转换为
int,double,float
Run Code Online (Sandbox Code Playgroud)
和
x,y,z
Run Code Online (Sandbox Code Playgroud)
通过使用macor之类的
UNZIP(i, seq)
Run Code Online (Sandbox Code Playgroud)
i索引在哪里
我想知道是否可以通过 Boost Preprocessor 序列完成以下操作。(大多数 SO 问题以及 Boost Preprocessor 示例仅讨论 1 个序列)
#define seq1 (a)(b)(c)
#define seq2 (1)(2)(3)
// Now iterate over both of them at the same time
Run Code Online (Sandbox Code Playgroud)
这是我的动机。我必须为很多类型定义几个函数,例如
void add(int val) { obj.AddInt(val); }
void add(double val) { obj.AddDouble(val); }
Run Code Online (Sandbox Code Playgroud)
我正在考虑定义两个序列,例如
#define types (int)(double)...
#define funcs (AddInt)(AddDouble)...
Run Code Online (Sandbox Code Playgroud)
然后为函数 add 编写一个宏,并迭代这两个序列。
我正在尝试做某种宏"重载",以便MACRO(某些东西)的扩展方式与MACRO(其他东西)不同.
使用我从这里得到的片段(我不确定它是否100%便携)和Boost PP库中的一些功能,我能够使它工作:D
//THESE TWO COUNT THE NUMBER OF ARGUMENTS
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
//THIS ONE RETURNS THE PARAMETER AT POSITION _i FROM A LIST OF __VA_ARGS__
#define VA_ARG(_i, ...) BOOST_PP_ARRAY_ELEM(_i, (VA_NARGS(__VA_ARGS__), (__VA_ARGS__)))
//AND THIS ONE IS THE 'OVERLOADED' MACRO ;)
#define TEST(...) BOOST_PP_IF(BOOST_PP_EQUAL(1, VA_NARGS(__VA_ARGS__)), function_A(VA_ARG(0, __VA_ARGS__)), \ //1 parameter
BOOST_PP_IF(BOOST_PP_EQUAL(2, VA_NARGS(__VA_ARGS__)), function_B(VA_ARG(0, __VA_ARGS__) + VA_ARG(1, __VA_ARGS__)), \ //2 parameters
BOOST_PP_IF(BOOST_PP_EQUAL(3, VA_NARGS(__VA_ARGS__)), function_C(VA_ARG(1, __VA_ARGS__) + …Run Code Online (Sandbox Code Playgroud) 我想知道是否有可能使用boost :: mpl / preprocessor或某些noce C ++ 11功能从类类型和函数名称创建函数代理。
说我们有:
inline void set_email(const ::std::string& value);
inline void set_email(const char* value);
Run Code Online (Sandbox Code Playgroud)
内部类电子邮件。我们知道有set_email函数,我们想用API创建一个prox类,例如
PROXY(Email, set_email, MyEmail)
Email * email = new Email();
MyEmail * myEmail = new MyEmail(email);
Run Code Online (Sandbox Code Playgroud)
并且有能力调用任何set_email重载。是否有可能以及如何创建这样的类来代理任何数量的不知道那里类型(仅名称)的重载函数?
我有这样的结构:
struct E1
{
typedef boost::tuple<
boost::optional< N::type_A >, // N - namespace
boost::optional< N::type_B >,
...................
boost::optional< N::type_X > //arbitrary number of, maximal is 7
> data_type;
// for access by name
boost::optional<N::type_A> const& type_A() const { return boost::get<0>(data); }
boost::optional<N::type_B> const& type_B() const { return boost::get<1>(data); }
.....................................
boost::optional<N::type_X> const& type_X() const { return boost::get<2>(data); }
data_type data;
};
Run Code Online (Sandbox Code Playgroud)
问:我如何使用BOOST预处理器创建这个结构?对我来说只知道type_A,type_B,...,type_X类型的名称.
这需要我,因为我必须创建很多这样的结构,只改变type_A,type_B,...类型.
在通常情况下,我可以使用boost预处理器数组还是设置?
我定义了一个宏,它是
#define TYPES (height,int,10)(width,int,20)
Run Code Online (Sandbox Code Playgroud)
如何使用像这样的 Boost Preprocessor 扩展这个宏?
int height = 10;
int width = 20;
Run Code Online (Sandbox Code Playgroud)
最多我能得到的是height,int,10和width,int,20作为字符串,但无法解析单个元素。
我想实现一个新的max / min宏,该宏可以采用两个以上的参数,例如:
#define max( ... ) ...
Run Code Online (Sandbox Code Playgroud)
然后,我可以像这样使用它:
max( p0, p1, p2, p3 )
max( 2, 4, 100 )
max( 1,2,3,4,5,6,7 ) -> 7
Run Code Online (Sandbox Code Playgroud)
这个宏是否可以帮助我们实现该宏?
#define PP_EXPAND(X) X
#define PP_ARG_COUNT(...) PP_EXPAND(PP_ARG_POPER(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
#define PP_ARG_POPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
#define PP_ARG_AT(Index, ...) PP_ARG_AT_##Index(__VA_ARGS__)
#define PP_ARG_AT_0(...) PP_EXPAND(PP_ARG_POPER(_1, _2, _3, _4, _5, …Run Code Online (Sandbox Code Playgroud) 例如
class A
{
int m_x;
float m_y;
double m_z;
int x() const {return m_x;}
float y() const {return m_y;}
double z() const {return m_z;}
};
Run Code Online (Sandbox Code Playgroud)
变得像
class A
{
MY_MACRO((int)(float)(double), (x)(y)(z));
};
Run Code Online (Sandbox Code Playgroud)
请使用boost预处理器序列来执行此操作,因为此宏将与已使用boost预处理器序列的其他现有宏组合.
我之前提出过以下问题,但解决方案在这种特殊情况下似乎不起作用.
我试图有条件地扩展包含逗号的宏.这是一个说明问题的示例:
#define TEST(...)\
BOOST_PP_REPEAT( \
BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
MACRO, \
BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))
#define MACRO(z, n, data) BOOST_PP_IF(1,MACRO_CONTAINING_COMMA(z, z),MACRO_CONTAINING_COMMA(z, z))
#define MACRO_CONTAINING_COMMA(_NAME, _NAME2) _NAME TIBRA_EATEN_COMMA() _NAME2
#define EATEN_COMMA BOOST_PP_IF(1,BOOST_PP_COMMA,BOOST_PP_TUPLE_EAT())
TEST(1,2,3,4)
Run Code Online (Sandbox Code Playgroud)
这扩展到
BOOST_PP_IIF BOOST_PP_IIF BOOST_PP_IIF BOOST_PP_IIF
什么时候应该扩展到
0,0 1,1 2,2 3,3