是否可以检查两个 类 是否具有相同的成员

Is it possible to check if two classes have the same members

struct Test1 : public Base {
    enum { type = 1 };
    int a;
    char ch;
    virtual void func1();
};

struct Test2 : public Base {
    enum { type = 2 };
    int a;
    char ch;
    virtual void func1();
};

我正在用 C++14 开发一个项目。由于某些兼容性原因,我必须像上面那样声明两个 class,它们的成员完全相同。

我的问题是是否有某种元编程方法可以让我检查两个 class 是否具有完全相同的成员?

真题

是的,我知道这很奇怪,但我确实遇到了这样的问题...

我正在开发一个网络服务器,上面每个class都是一个协议。

现在的问题是一些Android开发者错误地使用了协议Test1,所以我们不能碰它,因为用户可能不会更新他们的应用程序。我能做的就是添加另一个协议。所以我添加 class Test2.

由于这两个协议做的事情完全一样,我想确保它们始终相同。意思是,如果某天有人将成员添加到 Test1 但他忘记将成员添加到 Test2,我想得到一个编译时错误。

顺便说一句,我只关心数据成员,而不关心成员函数。

Is it possible to check if two classes have the same members

如果您可以升级到 C++20,并且 classes 是标准布局,并且您不关心类型的精确匹配,而是布局兼容性 - 这样一个 class 可能有一个 const 成员,而另一个有 non-const - 那么你可以使用 std::is_layout_compatible 类型特征。

否则,您可能不得不诉诸 meta-programming。


I want to make sure that they are always the same.

关于 XY-problem,如果您可以以 API 兼容的方式更改 Test1,那么继承可能是一个解决方案:

struct TestData : Base {
    int a;
    char ch;
};

template<int type>
struct TestBase : TestData {
    enum { type = type };
};

struct Test1 : TestBase<1> {
    void func1();
};

struct Test2 : TestBase<2> {
    void func1();
};

如果您根本无法触摸 Test1,那么一个棘手的解决方法是将其用作基础:

struct Test2 : Test1 {
    enum { type = 2 };
    void func1();
};

由于隐式转换,它并不理想。您可以通过使用私有继承来避免这些问题,但是您会遇到共享 public non-virtual Base.

的问题

我不喜欢这个问题的前提,因为它本质上是在寻求一种保持代码重复的方法。然而在实践中,狗屎发生了,如果有人想要两个具有相同内容的 classes,更好的想法是不要声明两个 classes 然后检查它们的兼容性,而是只声明它们一次。这可以通过使用基 class 或使用预处理器来完成。后一种情况还将防止任何新成员潜入派生的 classes,同时将新成员添加到两个 classes 中,只需要一次修改:

#define MAKE_CLASS(mp_name) \
struct mp_name : public Base { \
    enum { type = 1 }; \
    int a; \
    char ch; \
    void func1(); \
};
MAKE_CLASS(test1)
MAKE_CLASS(test2)