如何在没有代码重复的情况下统一实现双向转换?

BЈо*_*вић 6 c++ design-patterns data-structures

我在C遗留代码中使用了两个大的C结构,我需要从一个转换为另一个,反之亦然.像这样的东西:

#include <iostream>

struct A {
    int a;
    float b;
};
struct B {
    char a;
    int b;
};

struct C {
    A a;
    B b;
};

struct D {
    int a;
    char b;
    float c;
};

void CtoD( const C& c, D &d ) {
    d.a = c.a.a;
    d.b = c.b.a;
    d.c = c.a.b;
}
void DtoC( const D &d, C& c ) {
    c.a.a = d.a;
    c.b.a = d.b;
    c.a.b = d.c;
}

int main()
{
    C c = { { 1, 3.3f }, { 'a', 4 } };
    D d = { 1, 'b', 5.5f };

#if 0
    CtoD( c, d );
#else
    DtoC( d, c );
#endif

    std::cout<<"C="<<c.a.a<<" "<<c.a.b<<" "<<c.b.a<<" "<<c.b.b<<std::endl;
    std::cout<<"D="<<d.a<<" "<<d.b<<" "<<d.c<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

功能CtoDDtoC做同样的事情,但方向相反.改变一个结构需要改变它们.

为了最大限度地减少错误的可能性,并避免重复,我想实现某种映射,其中我只定义连接一次,然后我将一个值复制到另一个.这样,如果结构发生变化,则只需要进行一次更改.

所以,问题是:怎么做?可能有我可以使用的设计模式吗?


我的真实结构有数百个领域.以上只是简化的例子.

Lau*_*ZZA 1

让我们调皮一下吧...

struct rightwards_t {} rightwards;
struct leftwards_t {} leftwards;

template<typename Left, typename Right>
inline void map_field(Left& left, const Right& right, leftwards_t) {
    left = right;
}

template<typename Left, typename Right>
inline void map_field(const Left& left, Right& right, rightwards_t) {
    right = left;
}

template<typename Direction>
void convert(C& c, D& d, Direction direction) {
    map_field(c.a.a, d.a, direction);
    map_field(c.b.a, d.b, direction);
    map_field(c.a.b, d.c, direction);
}

// Usage
C c;
D d;
convert(c, d, leftwards); // Converts d into c
convert(c, d, rightwards); // Converts c into d
Run Code Online (Sandbox Code Playgroud)

真的不知道它是否有效(手头没有编译器),但我想写它。如果有人可以帮助我纠正它,请这样做。