Hallo zusammen, Was heisst Rfelexion in C++ und wofür soll gut sein? Der Begriff kenne ich von Java aber in C++ kenne ich gar nicht. Wie verwendet man das? Danke in voraus
ManuelGast schrieb: > Was heisst Rfelexion in C++ und wofür soll gut sein? Da haben sich schon die passenden Fachidiots an anderer Stelle drüber ausgelassen: https://www.c-plusplus.net/forum/106672-full Ich hab dergleichen nie gebraucht, vermisse es aber nicht. Wozu soll das gut sein und hält es was es verspricht?
ManuelGast schrieb: > Wie verwendet man das? Bis jetzt nocht gar nicht, da daran noch gearbeitet wird. C. A. Rotwang schrieb: > Ich hab dergleichen nie gebraucht, vermisse es aber nicht. Wozu soll das > gut sein und hält es was es verspricht? Nur um mal ein einfaches Beispiel zu nennen, dass nicht gleich Templateprogrammierung erfordert: Konvertieren von Enum Werten zu Strings mit dem Namen des Enum Werts. Bis jetzt kann man da nur irgendwas mit Macros zusammen basteln oder man schreibt es von Hand.
C. A. Rotwang schrieb: > Ich hab dergleichen nie gebraucht, vermisse es aber nicht. Wozu soll das > gut sein und hält es was es verspricht? Ja, oder wie man in Norddeutschland sagt: "Wat de Bur nicht kennt, dad frit hey nicht" ;-) Anderes Beispiel wäre Serialisierung.
Mir ist immer nicht klar wofür ist das gut? und wofür verwendet man das? Was gewinnt man daraus? Grund warum ich frage: gestern habe ich einen Vorstellungsgespräch gehabt und der Typ fragt mich, ob ich Reflection kenne? dann habe ich gesagt ja, der Begriff ist mir bekannt in Java aber in Standard C++ kenne ich nicht und habe ne benutzt. Dann sagte mir doch das gibt schon in C++ ..... ich verstehe immer noch wie und wofür ist das gut?
ManuelGast schrieb: > ich verstehe immer noch wie und wofür ist das gut? Immer wenn Du zur Laufzeit Informationen braychat die nur den Conpiler vorliegen.
ManuelGast schrieb: > Mir ist immer nicht klar wofür ist das gut? und wofür verwendet man das? > Was gewinnt man daraus? Du hast Deinem Gesprächspartner erzählt, Du kennst Reflection aus Java, weist aber nicht, wofür man das verwenden kann? > Grund warum ich frage: gestern habe ich einen Vorstellungsgespräch > gehabt und der Typ fragt mich, ob ich Reflection kenne? > dann habe ich gesagt ja, der Begriff ist mir bekannt in Java aber in > Standard C++ kenne ich nicht und habe ne benutzt. > Dann sagte mir doch das gibt schon in C++ ..... Der derzeitige Support für reflection in C++ ist relativ dürftig (man korregiere mich, wenn ich flasch liege). In C++ kannst Du z.B. auf eine feste Reihenfolge von Typen zugreifen. Du kannst ermitteln, ob A von B erbt. Du kannst aber nicht ermitteln, welche Basisklassen eine Klasse hat. > ich verstehe immer noch wie und wofür ist das gut? Mit reflection kannst Du auf im Algemeinen auf Informationen zu Datentypen zugeifen. Z.b. welche Member eine Klasse hat, welche Typen und Namen die haben etc. Also, die Möglichkeit, der Software über sich selbst zu Reflektieren. Sebastian hat als Beispiel z.B. Stringkonvertierungsfunktionen für Enums aufgeführt. Die könnte man sehr generisch implementieren, wenn man mit reflection ermitteln könnte, wie viele member ein enum hat und wie die heisen und welche Werte die haben.
Hier noch ein interessanter Blogpost von Jacki Kay zum Thema: http://jackieokay.com/2017/04/13/reflection1.html
Ich bilde in C manchmal reflection mittels Macros nach. z.B. so:
1 | #define ANIMALS \
|
2 | X(fox) \
|
3 | X(cat) \
|
4 | X(wulf)
|
5 | |
6 | #define X(Y) #Y,
|
7 | const char* animal_list[] = {ANIMALS}; |
8 | #undef X
|
9 | |
10 | #define X(Y) Y,
|
11 | enum animal_constants {ANIMALS animal_count}; |
12 | #undef X
|
wird zu:
1 | const char* animal_list[] = {"fox", "cat", "wulf",}; |
2 | enum animal_constants {fox, cat, wulf, animal_count}; |
So kann man einfach den Namen der Constante herausfinden: animal_list[fox] wäre "fox". Man kann auch durch alle Werte durchiterieren: for(size_t animal=0;animal<animal_count;animal++); animal ist dann jeweis der Index, und somit der Wert der Constante, und animal_list[animal] wäre der Name der Constante als string. So könnte man also auch vom String "cat" den Index in animal_list herausfinden und damit den Wert der Constante cat ermitteln. Ein anderes Beispiel wäre das Generieren von Parser code zum Einlesen von Werten in structs. Das habe ich z.B. bei diesem Projekt angewendet: https://github.com/Daniel-Abrecht/unitscript/blob/98b482270f9b1f2d5416b6c347af3b44d940866d/template/unitscript.template#L37 Ich binde einfach das Template ein, und der "yamlparser.generator" expandiert aus dem PARSABLE_STRUCTURES macro ein Struct und parser Funktionsdeklarationen. Wenn ich das Template aber mit -DUS_GENERATE_CODE compiliere, expandiert yamlparser.generator das PARSABLE_STRUCTURES macro in yaml parser code. Dies erspart mir haufenweise redundanten Code zu schreiben, und wenn ich eine andere Structur oder einen neuen Eintrag hinzufügen will, kann ich einfach einen BLOCK() oder ENTRY() zum PARSABLE_STRUCTURES macro hinzu, und muss nichts am parser code herumbasteln. Dies sind die einzigen nützlichsten Anwendungsfälle, die ich bisher hatte, wo reflection nützlich gewesen wäre. Als C++ feature fände ich es deshalb praktisch, wenn es compile time reflektion gebe mit der man Code generieren kann. Eine art Generator template, mit dem man durch Strukturmember hindurchiterieren kann, und je nach Membereigenschaften code generieren könnte. Irgendetwas in die richtung:
1 | template<struct A> |
2 | namespace MyParser { |
3 | A parse(std::string str){ |
4 | A a; |
5 | A:each(member) { |
6 | IfTypeEqual<member::type,int>::value:expand { |
7 | a.<member> = atoi(str); |
8 | }
|
9 | }
|
10 | return a; |
11 | }
|
12 | }
|
13 | |
14 | struct MyStruct { |
15 | int x; |
16 | }
|
17 | |
18 | MyParser<MyStruct> MyStructParser; |
19 | |
20 | int main(){ |
21 | auto a = MyStructParser::parse("123"); |
22 | std::cout << a.x << std::endl; |
23 | }
|
Soetwas in die richtung wäre wohl auch in C++20 möglich, aber ich glaube dort wird soetwas unnötig verkompliziert. Ausserdem finde ich runtime reflection überflüssig und überhaupt eine schlechte Idee.
Es gibt derzeit kein wirkliches Reflection in C++, es gibt aber einen Vorschlag für C++20: https://www.meetingcpp.com/blog/items/reflections-on-the-reflection-proposals.html https://www.youtube.com/watch?v=4AfRAVcThyA Was derzeit möglich ist, ist gewissermaßen eine "passive" Reflection über das Detection-Idiom bzw. SFINAE. Allerdings muss man da eben schon wissen, nach was man "sucht" (deswegen passiv). Eine Laufzeit-Enumeration aller bspw. Member geht derzeit nicht.
Torsten R. schrieb: > Hier noch ein interessanter Blogpost von Jacki Kay zum Thema: > http://jackieokay.com/2017/04/13/reflection1.html Zitat: "I believe reflection is an indispensible tool for generic libraries and huge frameworks that deal with lots of different types and complex relationships between those types" Im embedded-Bereich also Mikrocontroller gibt es eher wenige typen und deren Beziehung zueinander ist simple. Die benutzten Bisbliotheken würde ich jetzt auch nicht als "huge" bezeichnen. Kann man also davon ausgehen das in diesem Bereich reflections eher wenig von Vorteil für den Anwendungsprogrammierer sind? Welche Nachteile birgt eine reflections Implementierung in C++? Um welchen Faktor wird die erzeugte objectdatei aufgebläht?
C. A. Rotwang schrieb: > Welche Nachteile birgt eine reflections Implementierung in C++? Um > welchen Faktor wird die erzeugte objectdatei aufgebläht? Ich denke, dass beide, bis jetzt genannten Beispiel (enum zu Text und Serialisierung) durch eine generische Implementierung nicht größer werden würden, als wenn Du das für jeden verwendeten Typen von Hand schreibst. Das hängt aber natürlich vom zu Lösenden Problem und von der Lösung ab.
:
Bearbeitet durch User
Qt bietet für alle Klassen, die von QObject abgeleitet sind, und einige zusätzliche Typen sowas wie reflection. Dort wird aber der Meta Object Compiler verwendet, um diese Informationen zu generieren.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.