template vs. #define!?
-
Hallo Leute,
ich spiele grad bisschen mit C++ template rum, und hab mal ein "blöde" Frage:
sagen wir mal ich habe ein struct
typedef struct Comp { uint16_t ValA; uint16_t ValB; uint16_t ValC; uint16_t ValD; } Comp;und will mittels eine makros generisch auf einen best. parmater des structur selektieren:
#define Selector(x,Y) (uint16_t)(((Comp)x).Val##Y); uint16_t t= Selector(a,A);geht sowa auch via templates ?
template <???> class Selector { public: Selector(Comp inst) { uint16_t x = inst.Val???; } };bitte fragt mich nich nach dem grund.. sonder einfach nur ob es möglich ist?
Grüßle
-
std::tuple...

-
Soweit ich weiß, geht das im allgemeinen nicht. Das ginge höchstens mit Reflections und ob und wann die mal Teil des Standards werden steht in den Sternen. Man könnte vielleicht ein Template für jeden sinnvollen char wert spezialisieren, aber da muss ich noch mal drüber nachdenken bevor ich ein Beispiel präsentieren kann.
-
Vielleicht so etwas in der Art (ungetestet):
template<class T> class selector<char> { }; template<class T> class selector<'A'> { static auto select(T obj) -> decltype( obj.ValA) {return obj.ValA;} }; template<class T> class selector<'B'> { static auto select(T obj) -> decltype( obj.ValB) {return obj.ValB;} };usw.
Dann könntest du So damit zugreifen:
uint16_t t = selector<'A'>::select(a);
-
NullBockException schrieb:
sagen wir mal ich habe ein struct
typedef struct Comp { uint16_t ValA; uint16_t ValB; uint16_t ValC; uint16_t ValD; } Comp;Diese struct ist total unhandlich. Richtig modelliert sähe das so aus:
struct Comp { uint64_t Vals[4]; };Dann kannst du dynamisch per Index zugreifen. Wenn du den Elementen Namen geben willst
enum class CompVal { A=0, B, C, D };Alles andere (siehe Code von TNA) sind Workarounds um ein schlechtes zugrundeliegendes Design.
-
Absolut... aber leider sind die structs teil einer api... hardware schnittstelle
ich mach es jetzt so ungefähr:
uint16_t *p = ((uint16_t*)&Comp); p[0] = ...; // entspricht A p[1] = ...; // entspricht Busw;)
-
Naja es gibt Member-Pointer ("pointer to member").
Die C++ Variante von "offsetof" halt.
-
Guten Morgen Hustbear.. kannst du mir das mal genau erläutern:)
-
Ein Member-Pointer identifiziert sozusagen die "Position" eines Unterobjekts, also eines Member eines anderen Objekts. Ohne dabei aber das Hauptobjekt festzulegen.
Die Syntax ist etwas gewöhnungsbedürftig:typedef uint16_t Comp::*CompPart; // Typedef auf einen "pointer to member" (Deklaration ist wie üblich das selbe ohne das Keyword "typedef")Deine "A", "B", "C" werden dann einfach zu Instanzen dieses Typs.
typedef uint16_t Comp::*CompPart; static CompPart const Comp_ValA = &Comp::ValA; static CompPart const Comp_ValB = &Comp::ValB; static CompPart const Comp_ValC = &Comp::ValC; uint16_t Selector(Comp const& c, CompPart p) { return c.*p; // c.*p ergibt das Member an "Position" p im Objekt c } Comp theComp; uint16_t someA = Selector(theComp, Comp_ValA); // oder direkt uint16_t someB = Selector(theComp, &Comp::ValB);Geht natürlich genau so über einen non-type Template Parameter. (Wobei man bei Verwendung eines Tempaltes keine Member-Pointer bräuchte, man könnte dazu auch eine kleine Hilfsklasse pro Member schreiben die man dann als Type-Parameter an das Template übergibt.)