是否可以检查两个 类 是否具有相同的成员
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)
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)