我知道,在C++中,没有反射。但是,我需要在编译时迭代变量并为它们生成代码。
我拥有的是这个:
class Foo {
int x;
double y;
Foo() {
Register(x, "x");
Register(y, "y");
}
template <typename T>
void Register(T val, const std::string & key){
//do something with val and key
}
}
但是,我想为每个变量自动调用Register
。有时,它们可能有很多,很容易忘记注册某些内容或在key
中输入拼写错误(键最好与变量名相同)。
我想CREATE_AND_REGISTER(x, "x")
宏这样的东西,但我不知道这是否可能。我已经看到了一些基于 Boost 的解决方案,但我只需要普通的 C+11/14。
我认为不可能做真正想要的事情("没有反射"),但是......
我想到了类似CREATE_AND_REGISTER(x,"x")宏的东西,但我不知道是否有可能
我认为c宏是蒸馏邪恶的,但是...如果你真的想要,如果你接受int x
和float y
被包裹在结构中......我提出以下宏
#define DEFandREGIS(type, name, def)
struct bar_##name
{
type var;
bar_##name (type val, foo * t) : var{val}
{ t->regis(var, #name); }
};
bar_##name b##name{def, this};
接收类型(int
、float
、...)、名称(x
、y
、...)和默认值
因此(如果默认值对您来说足够了),您可以按如下方式定义foo
struct foo
{
DEFandREGIS(int, x, 1)
DEFandREGIS(float, y, 2.2)
template <typename T>
void regis (T val, std::string const & key)
{ std::cout << "regis(" << val << ", "" << key << "")" << std::endl; }
};
并且,定义一个foo
变量,你会被打印出来
regis(1, "x")
regis(2.2, "y")
如果你想要一个foo
构造函数,该构造函数可以使用不同的(不是默认值)创建x
和y
,则可以确认默认构造函数(如果需要)并创建另一个构造函数,如下所示
foo () = default;
foo (int x0, float y0) : bx{x0, this}, by{y0, this}
{ }
如果你的Register()
方法(在我的例子中是regis()
)可以是一个static
方法,那么bar##x
中不需要this
指针,你可以稍微简化一下这个例子。
以下是完整的工作示例
#include <iostream>
#define DEFandREGIS(type, name, def)
struct bar_##name
{
type var;
bar_##name (type val, foo * t) : var{val}
{ t->regis(var, #name); }
};
bar_##name b##name{def, this};
struct foo
{
DEFandREGIS(int, x, 1)
DEFandREGIS(float, y, 2.2f)
foo () = default;
foo (int x0, float y0) : bx{x0, this}, by{y0, this}
{ }
template <typename T>
void regis (T val, std::string const & key)
{ std::cout << "regis(" << val << ", "" << key << "")" << std::endl; }
};
int main()
{
foo a;
foo b{3, 4.4f};
}