It took me a while to figure out how to do this. And I came out with the following solution:
#include <iostream> #include <algorithm> #include <cstring> 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; }; template< typename T1, typename T2 > struct DataField { static inline void Update( const T1 & src, T2 & dst ) { dst = src; } static inline void Update( T1 & dst, const T2 & src ) { dst = src; } }; template<> struct DataField< const char*, char* > { static inline void Update( const char* src, char* dst ) { strcpy( dst, src ); } }; template<> struct DataField< char*, const char* > { static inline void Update( char* dst, const char* src ) { strcpy( dst, src ); } }; template< typename T1, typename T2, int N > struct DataField< T1[N], T2[N] > { static inline void Update( const T1 (&src)[N], T2 (&dst)[N] ) { std::copy_n( src, N, dst ); } static inline void Update( T1 (&dst)[N], const T1 (&src)[N] ) { std::copy_n( src, N, dst ); } }; template< typename T1, typename T2 > void UpdateDataField( T1 & src, T2 & dst ) { DataField< T1, T2 >::Update( src, dst ); } template< typename T1, typename T2 > void UpdateMappedDataFields( T1 & src, T2 & dst ) { UpdateDataField( src.aa, dst.a ); UpdateDataField( src.ab, dst.c ); UpdateDataField( src.ba, dst.b ); } void CtoD( const C& c, D &d ) { UpdateMappedDataFields( c, d ); } void DtoC( const D &d, C& c ) { UpdateMappedDataFields( c, d ); } 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="<<caa<<" "<<cab<<" "<<cba<<" "<<cbb<<std::endl; std::cout<<"D="<<da<<" "<<db<<" "<<dc<<std::endl; }
All data field mappings are performed in the UpdateMappedDataFields function and only there.
What I don't like is that the UpdateMappedDataFields function is a template and the way it is implemented prevents auto-completion when using the IDE, since the types are not known.
However, I still would like to hear if there is a better way.