c++ - 有没有办法在成员名称循环中对 N C++ 类成员应用操作(可能通过预处理器)?

标签 c++ reflection c-preprocessor

问题:

我有一个 C++ 类,其中包含大量(>100)个行为几乎相同的成员:

  • 同类型

  • 在一个函数中,每个成员都有与其他成员相同的代码,例如从构造函数中的映射赋值,其中映射键与成员键相同

  • 这种行为的相同性在许多函数 (>20) 中重复出现,当然每个函数的行为都不同,因此无法将事情分解开。

  • 成员列表非常灵活,不断添加,有时会删除,一些(但不是全部)是由更改数据库表中的列驱动的。

正如您所想象的,就代码创建和维护而言,这会带来很大的麻烦,因为要添加新成员,您必须向每个函数添加代码 使用类似成员的地方。

我想要的解决方案示例

我需要的实际 C++ 代码(例如,在构造函数中):

MyClass::MyClass(SomeMap & map) { // construct an object from a map 
    intMember1 = map["intMember1"];
    intMember2 = map["intMember2"];
    ... // Up to 
    intMemberN = map["intMemberN"];
}

我希望能够编写的 C++ 代码:

MyClass::MyClass(SomeMap & map) { // construct an object from a map 
#FOR_EACH_WORD Label ("intMember1", "intMember2", ... "intMemberN")
    $Label = map["$Label"];
#END_FOR_EACH_WORD
}

要求

  • 解决方案必须与 GCC 兼容(如果重要的话,将 Nmake 作为 make 系统)。 不要关心其他编译器。

  • 解决方案可以在预处理器级别或可编译的级别上。我对任何一个都很好;但到目前为止,我所有的研究都让我得出结论,后者在 C++ 中显然是不可能的(我非常想念 Perl,因为我被迫使用 C++!)

  • 解决方案必须至少在某种程度上是“行业标准”(例如,Boost 很棒,但 Joe-Quick-Fingers 曾经创建并发布在他的博客上的自定义 Perl 脚本不是。哎呀,我可以轻松编写 Perl 脚本,我更像是 Perl 专家而不是 C++ 专家 - 我只是无法让我的 BigCompany 软件工程领域的大佬们购买使用它 :) )

  • 该解决方案应该允许我声明一个 ID 列表(理想情况下,只在一个头文件中而不是像我在上面的示例中所做的那样在每个“#FOR_EACH_WORD”指令中声明)

  • 解决方案绝不能局限于“从数据库表创建对象”构造函数。有很多函数需要这个,其中大多数不是构造函数。

  • “将所有值都放在一个 vector 中,然后在 vector 中运行‘for’循环”的解决方案是一个显而易见的解决方案,无法使用 - 许多人使用的库中的代码应用程序,成员是公开的,遗憾的是,重写这些应用程序以使用 vector 成员而不是命名成员是不可能的。

最佳答案

Boost 包含一个很棒的预处理器库,您可以使用它来生成此类代码:

#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/cat.hpp>

typedef std::map<std::string, int> SomeMap;

class MyClass
{
public:
    int intMember1, intMember2, intMember3;

    MyClass(SomeMap & map) 
    {
        #define ASSIGN(z,n,_) BOOST_PP_CAT(intMember, n) = map[ BOOST_PP_STRINGIZE(BOOST_PP_CAT(intMember, n))];
        BOOST_PP_REPEAT_FROM_TO(1, 4, ASSIGN, nil)
    }
};

关于c++ - 有没有办法在成员名称循环中对 N C++ 类成员应用操作(可能通过预处理器)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1367649/

相关文章:

c++ - 参数化警告消除宏问题

c++ - 仅为派生类启用模板化基类

java - 单个 Aspect 中针对相同方法执行切入点的多个建议 - Spring AOP

c++ - 使用GCC对C文件进行部分预处理(不删除 “define”指令)

c++ - 如何避免 C++ 中的多重定义?

c++ - 用户终止进程时发出信号?

reflection - 如何在不实际硬编码路径的情况下确定记录中字段的 json 路径?

c - 在 C 中初始化数组时出错

c++ - 如何在 Linux 上关闭 gcc 预处理器?

c++ - 数组循环不能正常工作? C++