Makroästhetik
-
Okay, der Thread hätte eher "Makro-Ästhetik" heißen sollen

Derzeit schreibe ich für ein Projekt einige Makros und Template-Klassen, die das Implementieren und Benutzen von Interfaces im COM-Stil vereinfachen. Gegenwärtig sieht das so aus:
UCL_DECL_INTERFACE (imgeval::, IDataPointInfo, ucl::oo::IInterface, "{9A63B541-6E23-4995-9740-28FE1DCC54DA}") { UCL_DECL_FUNC0 (DataTypeT, GetType) UCL_DECL_PROC1 (SetType, DataTypeT,type) ... }; class DataPointInfo : public IDataPointInfo { private: DataTypeT dataType; public: UCL_IMPL_QUERYINTERFACE (DataPointInfo, void /* d.h. keine Basisklasse */, IDataPointInfo) UCL_IMPL_ADDREF_RELEASE UCL_DEF_FUNC0 (DataTypeT, GetType) { return dataType; } ... };Die meisten Aspekte stehen bereits zur Zufriedenheit - das meiste hat sich nach einiger Benutzung der Makros eingependelt -, aber ein ästhetisches Problem bleibt: es ist verdammt schwer, in obiger Notation auf Anhieb zwischen Prozeduren und Funktionen zu unterscheiden, z.B.: ist SetType bei der zweiten Methode Rückgabewert oder Methodenname? Die Differentation in UCL_DECL_PROCx und UCL_DECL_FUNCx ist leider (meinem gegenwärtigen Kenntnisstand zufolge) makrotechnisch notwendig, da beide Makros zu einer OLE-konformen Methode (mit HRESULT-Rückgabewert) expandiert werden, also etwa so (stark verkürzt):
struct IDataPointInfo : ucl::oo::IInterface { inline DataTypeT GetType (void) { DataTypeT retval; HRESULT hresult; if ((hresult = _GetType (retval)) != 0) ucl::oo::ESafecallException::raise (hresult); return retval; } virtual HRESULT __stdcall _GetType (DataTypeT& retval) = 0; inline void SetType (DataTypeT type) { HRESULT hresult; if ((hresult = _GetType (type)) != 0) ucl::oo::ESafecallException::raise (hresult); } virtual HRESULT __stdcall _SetType (DataTypeT type) = 0; ... };Entsprechend generieren UCL_DEF_FUNCx und UCL_DEF_PROCx Exception-Handler um die Funktion herum.
Hat jemand Vorschläge, wie ich eine deutlichere Unterscheidbarkeit forcieren könnte? (Es komme bitte niemand mit der Idee, bei Prozeduren den Namen einfach einzurücken.) Ideal wäre, wenn ich
UCL_DECL_FUNC1 (void, SetType, DataTypeT,type)benutzen könnte, aber ich wüßte nicht, wie das gehen sollte. Und
UCL_DECL_PROC1 (void, SetType, DataTypeT,type)möchte ich auch vermeiden, weil es redundant und damit fehleranfällig ist.
Edit: Kleinigkeiten (DECL <> DEF)
-
audacia schrieb:
Ideal wäre, wenn ich
UCL_DECL_FUNC1 (void, SetType, DataTypeT,type)benutzen könnte, aber ich wüßte nicht, wie das gehen sollte.
So, ich bin mittlerweile darauf gekommen, daß und wie es mit ein wenig Präprozessormagie doch funktionieren kann:
#define UCL_PP_IS_VOID(type) \ UCL_PP_PAIR(UCL_PP_2ND, (UCL_PP_CAT2(UCL_PP_IS_VOID_TST_, type, 0, 0))) #define UCL_PP_IS_VOID_TST_void 0, 1,Danke dennoch für die zahlreichen Reaktionen
