有一个无法修改的旧代码。如果简化它看起来像这样:
enum class Type {A, B, C};
struct Object {Type type;};
Object* objs[N];
int count = 0;
#define addobj(ptr) objs[count++] = (Object*)ptr
struct A {
Type type;
int prop1;
A(int v) : type(Type::A), prop1(v) {addobj(this);}
};
struct B {
Type type;
int prop1;
B(int v) : type(Type::B), prop1(v) {addobj(this);}
};
struct C {
Type type;
int prop1;
C(int v) : type(Type::C), prop1(v) {addobj(this);}
};
A* getA(int id) {return (A*)objs[id];}
B* getB(int id) {return (B*)objs[id];}
C* getC(int id) {return (C*)objs[id];}
此外,还有“多态”属性访问,允许更改:
int& prop1ref(int id) {
switch (objs[id]->type) {
case Type::A: return getA(id)->prop1;
case Type::B: return getB(id)->prop1;
}
return getC(id)->prop1;
}
void test() {
A a(1); B b(2); C c(3);
for (int id=0; id<count; id++)
prop1ref(id);
}
有没有办法只用 std::variant 和 std::visit 替换 prop1ref 中的属性访问代码?
请注意,prop1 名称和类型在类之间确实匹配,但位置(偏移量)不匹配。类型字段偏移得到保证,因此始终可以进行转换。此外,新代码应允许在不使用宏的情况下访问 A、B、C 类中的双 prop2、字符串 prop3 等。