C++11 - 获取编译时的所有类变量,并在没有 Boost 的情况下为它们调用方法



我知道,在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 xfloat 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};

接收类型(intfloat、...)、名称(xy、...)和默认值

因此(如果默认值对您来说足够了),您可以按如下方式定义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构造函数,该构造函数可以使用不同的(不是默认值)创建xy,则可以确认默认构造函数(如果需要)并创建另一个构造函数,如下所示

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};
}

相关内容

最新更新