C++ runterbrechen von nested variant

cwriter

Erfahrenes Mitglied
Das Templateargument von get ist der Rückgabetyp. Da fehlt eine recursive_wrapper-Ummantelung.

Gruss
cwriter
 

jkallup

Erfahrenes Mitglied
nun habe ich das so:

Code:
        auto *mp1 = boost::get<boost::recursive_wrapper<cmd_varset<TypeDouble<int>>>>(&exp1);
        auto *mp2 = boost::get<boost::recursive_wrapper<cmd_varset<TypeDouble<int>>>>(&exp2);
       
        auto *mp3 = boost::get<boost::recursive_wrapper<cmd_varset<TypeDouble<int>>>>(&mp1);

was hierzu führt:
main.cpp: In function 'kallup::expression_wrapper::expression kallup::eek:perator+(kallup::expression_wrapper::expression&, kallup::expression_wrapper::expression&)':
main.cpp:72:91: error: no matching function for call to 'get<boost::recursive_wrapper<kallup::cmd_varset<kallup::TypeDouble<int> > > >(boost::recursive_wrapper<kallup::cmd_varset<kallup::TypeDouble<int> > >**)'
auto *mp3 = boost::get<boost::recursive_wrapper<cmd_varset<TypeDouble<int>>>>(&mp1);
 

cwriter

Erfahrenes Mitglied
main.cpp:72:91: error: no matching function for call to 'get<boost::recursive_wrapper<kallup::cmd_varset<kallup::TypeDouble<int> > > >(boost::recursive_wrapper<kallup::cmd_varset<kallup::TypeDouble<int> > >**)'
exp1 ist schon ein Pointer. Das & macht daraus **, sodass als Templateargument ein Pointer erwartet wird. Nimm das & weg.

Gruss
cwriter
 

jkallup

Erfahrenes Mitglied
Hallo,

ich habe dieses Problem lösen können: es muss lauten:
Code:
auto *mp1 = boost::get<boost::recursive_wrapper<cmd_varset<TypeDouble<int>>>>((&exp1));
jetzt frag mich aber nicht warum exp1 in Klammern stehen muss.
Der Compiler ist nun zufrieden und gibt nur noch die Meldung aus, das mp1 nicht genutzt wird.
Aber das kommt noch.
Also dann Auf der Gleichen Stelle, auf der Gleichen Welle....

Gruß
Jens
 

cwriter

Erfahrenes Mitglied
ich bekomme noch die Krise - wie komm ich auf die "double" Werte von TypeDouble<int>?
C++:
auto t = TypeDouble<int>();
auto val = t.value;
Naja. Und bei deinem Code:
jetzt frag mich aber nicht warum exp1 in Klammern stehen muss.
Weil es nicht muss? Die Klammern machen gar nichts.

Fehler auf Zeile 76:
Der cmd_varset-Konstruktor erwartet ein TypeDouble<int> als Parameter, du gibst einen recursive_wrapper.
g++ hat gesagt.:
note: no known conversion for argument 1 from 'boost::recursive_wrapper<kallup::cmd_varset<kallup::TypeDouble<int> > >*' to 'kallup::TypeDouble<int>'
Und später, bei ex1: Das ist nicht mal definiert...

Programmierst du eigentlich probabilistisch oder hast du einen Plan, was du machen willst? Das sieht mir alles doch recht stark nach einfach Durchprobieren aus.

TypeDouble<int> macht noch immer keinen Sinn, entweder ist etwas double floating point, oder es ist int, das Argument nutzt du ja nicht mal. Warum du einen recursive_wrapper brauchen willst, verstehe ich auch nicht, und es macht auch keinen Sinn, falls das Anwendungsgebiet (wie ich vermute) ein Skriptparser sein soll, dann gibt es niemals Rekursion in Ausdrücken (nur in der Ausführung davon, was irrelevant ist, da der String "funktion()" nicht selbst eine Funktion aufrufen kann, sondern zu einem Funktionsaufruf evaluiert wird.
Ein cmd_varset ist ebenso sinnlos, da es (zumindest momentan) nur einen TypeDouble<int> halten kann.
Und dann hast du eine neue Klasse expression_wrapper gemacht, die ein Typedef hält (was, warum denn ein Typedef? Du hast ja nicht einmal eine Instanz davon!) und das Ganze packst du dann in eine glorifizierte Union, welche nur glorifiziert ist, damit du non-constant classes darin aufbewahren kannst, und du packst dann ausschliesslich Klassen mit konstanten Methoden rein? (Die variant ist nur dann besser als union, wenn du zwischen Klassen hin- und herwechseln willst. Wenn du nur einmal den Typ setzt, ist die Variant overkill).
Wenn du eine expression (oder expression_wrapper) - Klasse haben willst, warum machst du es nicht ganz klassisch mit Vererbung? "class add_expression : public expression" oder so?
Du hast gerade mal 100 Zeilen Code und hast es geschafft, das so zu komplizieren, dass du keinen funktionierenden Code hinbekommst, weil du so banale Dinge wie Type Mismatches nicht selbst auflösen kannst.
Das einzige, was ich nicht ganz verstehe, ist die Sache mit dem static_get, aber die restlichen Fehlermeldungen sind eigentlich klar.

Ok, es ist dein Design, und dein Ansatz mit der Variant mag funktionieren (wenn ich es auch nicht wirklich für sinnvoll erachte), aber so die allerbanalsten Fehlermeldungen solltest du schon selbst verstehen können...

Gruss
cwriter
 

jkallup

Erfahrenes Mitglied
sodele, Zwischenbilanz:
Hab mal alles schön aufgeräumt, und siehe da ex funktioniert schon.
Was ich nicht verstehen:
schau Dir mal Zeile 35 ... Der GnuC++ Compiler scheint das nicht zu raffen, das man
die Zeile so wie jetzt auch abkürzen könnte .. aus zwei Anweisungen mach eine.
so ist:
TypeDouble<int> td; td = exp;

für ihn richtig.
Aber worüber man stolpert ist:
TypeDouble<int> td = exp;

Lustigerweise bringt der Compiler Meldungen so zustande, das wenn oben alles ok ist
unter wieder was fehlt. oder umgekehrt.
Bis man die Eigenheiten rausgewusselt hat, da is ja ne Alte Dame Jungfrau geworden.

Aber Danke für Deine Hilfe
Jens

P.S.: hier ein kurzer Aschnitt, der funktioniert - alsi erstmal kompiliert:
http://coliru.stacked-crooked.com/a/961a177e6a071a84

Da zeigt der Compiler zwar, das res nicht benutzt wird, aber das war/ist erstmal zweitrangig.
Oh Man ich soche Dir, des wo nen Krompf.