【发布时间】:2026-01-04 09:40:01
【问题描述】:
是否有任何内置的 C++ 机制能够自动生成代码以在类的每个成员上调用函数或运算符?
例如,如果我们有数百种类型需要使用一组特定的函数或运算符。在每个类型中,每种类型都需要为其所有成员调用相同的函数或运算符(仅此而已)。
对于一些具体的例子,我们可以说这些类型有函数Save()和Load(),或者流操作符<<和>>。当TYPE::Save(stream s)被调用时,我们如何自动执行A.Save(s) + B.Save(s) + C.Save(s)?如果代码只是简单地将执行传递给所有成员,有没有办法自动化这个过程?
这里是一些将自动生成的代码示例(只是Save() 函数)。 编辑注意:本例将所有 3 个成员显示为同一类型,但该解决方案应该适用于任何类型组合的成员,只要它们都共享相关的函数/运算符
class TYPE
{
protected:
XTYPE A, B, C;
public:
void Save(stream s)
{
A.Save( s );
B.Save( s );
C.Save( s );
}
};
我的一个旧引擎使用疯狂的循环宏来实现这一点。它使使用宏构建类型变得更加容易(当有数百个类使用它们时),并且生成的类不难理解,但是宏本身很混乱且过于复杂。我希望有更多的东西......内置到语言中。
【问题讨论】:
-
不是开箱即用的,我认为您正在寻找的东西将被称为编译时反射之类的东西。搜索那个词我发现了这个:veselink1.github.io/blog/cpp/metaprogramming/2019/06/08/…也许它适合你。
-
在 C++ 中,这通常通过代码生成来解决,但实际上基于宏的解决方案也是可能的。
-
传统智慧是,每当您认为要“迭代多个变量”时,都应该将它们改为数组(或其他适当的容器)。然后一个简单的循环就足够了。当然有时这可能不合适,但有时最简单的解决方案是最好的。
-
您可以使用参数包。
struct TYPE_BASE { XTYPE A, B,C; }; template<typename Base, auto...Members> struct ImplementSpecialMembers : Base { void Save(stream s) { ((this->*Members).Save(s),...); }; class TYPE : public ImplementSpecialMembers<TYPE_BASE, &TYPE_BASE::A, &TYPE_BASE::B, &TYPE_BASE::C> {}; -
可以使用数组或列表代替普通成员。但我们自动生成的函数只是次要任务,与类型没有任何具体关系。或者换句话说,我们不想(完全)重新设计我们所有预先存在的类型,只是为了自动化流操作。