C++ 在编译时注册类成员 var
C++ Register class member var's at compile time
我尝试使用boost MPL和fusion实现一个类似Java的注释系统。
为什么需要:我需要对成员var进行注释,以获得一些特殊的运行时特性。我在编译时注册并尝试它们到我的基类中,如下所示:
class foo
{
INIT()
$REGISTER("test1")
int test1 = 5;
$REGISTER("b")
char* b = "rndmText";
....
}
我的目标是指针和类似$REGISTER(&a,"a")的文本的组合,但这是未来的目标。。。
基类处理所有必要的东西。寄存器宏创建一个融合向量:
#define INIT()
typedef boost::fusion::vector0<> BOOST_PP_CAT(registered, BOOST_PP_SUB(__COUNTER__,2));
boost::fusion::vector0<> BOOST_PP_CAT(list,BOOST_PP_SUB(__COUNTER__,2));
#define EXPORT(arg)
typedef boost::fusion::result_of::push_back< BOOST_PP_CAT(registered, BOOST_PP_SUB(__COUNTER__,4)), const char*>::type BOOST_PP_CAT(registered, __COUNTER__);
BOOST_PP_CAT(registered, BOOST_PP_DEC(__COUNTER__)) BOOST_PP_CAT(list, BOOST_PP_SUB(__COUNTER__,1)) = boost::fusion::make_list(BOOST_PP_CAT(list,BOOST_PP_SUB(__COUNTER__,7)), arg);
这扩展到(在我的情况下):
typedef boost::fusion::vector0<> registered18;
boost::fusion::vector0<> list19;;
typedef boost::fusion::result_of::push_back< registered18, const char*>::type registered23;
registered23 list24 = boost::fusion::make_list(list19, "test1");;
int test1 = 5;
typedef boost::fusion::result_of::push_back< registered23, const char*>::type registered28;
registered28 list29 = boost::fusion::make_list(list24, "b");;
char* b = "rndmText";;
问题是:boost::fusion::make_list(…,"test1")创建了一个编译器错误,我不知道如何修复它。这就是错误:
boost::fusion::joint_view<Sequence,const boost::fusion::single_view<const char *>>::joint_view(const boost::fusion::joint_view<Sequence,const boost::fusion::single_view<const char *>> &)' : cannot convert argument 1 from 'boost::fusion::list<T,const char (&)[6],boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_>' to 'const boost::fusion::joint_view<Sequence,const boost::fusion::single_view<const char *>> &'
有人能帮我或者有更好的主意吗?
Dominik
这对编译错误没有真正的帮助(抱歉),但时间太长,无法发表评论。
有人能帮忙/或有更好的主意吗?
我认为你在滥用宏。请考虑以下客户端代码:
class foo: public registered<foo> {
int test1 = 5;
char* b = "rndmText";
public:
foo();
virtual ~foo() = default;
};
foo::foo() : registered<foo>{ "foo" } {
register(&i, "i"); // part of the interface of the base class
register(&b, "b");
}
说明:
现在,基类提供了相同的功能。CRTP实现意味着,如果有两个(或多个)从registered
继承的类,则它们不在同一类层次结构中(因为元数据的删除不应在不相关的具体类之间强加类关系)。
registered<T>
的实现可以在内部使用boost::fusion
(或者如果需要的话,可以使用其他东西),并且可以将三米长的声明隐藏在一个方便的别名后面(例如using data_sequence = boost::fusion::vector0<>
)。
INIT()
部分将在registered<T>
实例(和公共接口)的构建中自然进行。
此实现完全避免了宏,并允许您以更优雅的方式向客户端代码公开元数据,可能只需从registered<T>
的API导入即可。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 嵌套在类中时无法设置成员数据
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将函数类成员映射到类本身内部
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 如何在类中进行 c++ 多线程处理(将线程引用保留为成员 var)
- C++ 在编译时注册类成员 var
- c++数组[var][2]作为类成员