C++ (Qt)void CopyParam( MyClass & dst, const MyClass & src, int id ){ switch (id) { case ID_ENABLED: if (dst.mEnabled != src.mEnabled) { SaveUndo(dst); dst.mEnabled = src.mEnabled; UpdateUI(); } break; case ID_COUNT: if (dst.mCount != src.mCount) { SaveUndo(dst); dst.mCount = src.mCount; UpdateUI(); } break; ...// и так еще много-много раз}
C++ (Qt)template<class T, class M>void work (const T &dest, M &destMember, const M &sourceMember){ if (destMember != sourceMember) { SaveUndo(dest); destMember = sourceMember; UpbateUI(); }} switch(id) { case ID_ENABLED: work(dst, dst.mEnabled, src.mEnabled); break;.....}
C++ (Qt)void work (const T &dest, M &destMember, const M &sourceMember, bool updateUI = false, bool action1 = false........)
C++ (Qt)worj(dst, dst.mCount, src.mCount, false, true, false);
C++ (Qt)int MyClass::count( void ) const { return count; }void MyClass::setCount( int cnt ) { count = cnt; }
C++ (Qt)class AbstractStrategy{ virtual bool canDo(int id) const = 0; virtual void do(MyClass & dst, const MyClass & src) = 0;}
C++ (Qt)class BoolMethodStrategy : public AbstractStrategy{public: BoolMethodStrategy(std::function<bool(MyClass*)> getMethod, std::function<void(MyClass*, bool val)> setMethod); virtual void copy(MyClass & dst, const MyClass & src) { if (getMethod_(&dst) != getMethod_(&src)............ }} ....................map[1] = new BoolMethodStrategy(&MyClass::enabled, &MyClass::setEnabled)
class MyClass{public: MyClass(bool enabled, int count) : enabled(enabled), count(count) {} bool enabled; int count;};/// Field IDsstatic const int ID_ENABLED = 0;static const int ID_COUNT = 1;/// Primary class template and its specializations to map field Id to field pointertemplate <int Id> struct MemberById;template <> struct MemberById<ID_ENABLED> { static constexpr auto Member = &MyClass::enabled; };template <> struct MemberById<ID_COUNT> { static constexpr auto Member = &MyClass::count; };...template <int Id>void CopyParam(MyClass& dst, const MyClass& src){ auto& dstMember = dst.*MemberById<Id>::Member; const auto& srcMember = src.*MemberById<Id>::Member; if (dstMember != srcMember) { SaveUndo(dst); dstMember = srcMember; UpdateUI(); }}Usage: MyClass src(false, 0); MyClass dst(true, 1); CopyParam<ID_ENABLED>(dst, src); CopyParam<2>(dst, src); // compile-time error: 2 is not covered
template <int Id> struct MemberById;template <> struct MemberById<ID_ENABLED> { static constexpr auto Member = &MyClass::enabled; };
C++ (Qt)const iint id[] = { ID_ENABLED, ID_COUNT, ... };for (int i = 0; i = sizeof(id) / sizeof(int); ++i) CopyParam <???> // но ведь нельзя подставить i