Wann std::any benutzen?



  • Ich verstehe wie std::any funktioniert, sehe aber nicht wann es nuetzlich sein koennte. Kann mir jemand ein Beispiel geben wann es sinnvoll ist std::any zu verwenden?



  • Ich nutze gerade ein Framework 'Wt' (ähnlich wie qt).
    In deren abstrakten Model-Klasse (also model/view) sieht die data funtion so aus:

    boost::any data(int column, int row);
    

    In einer Spalte kann ja ein string, in der nächsten ein double, usw... sein.
    Ist halt eine Möglichkeit das umzusetzen.



  • Gutes Beispiel! Danke.



  • Irgendwo wird das ja so benutzt, aber dann kann man sich mal wieder darüber streiten, ob man das nicht immer hätte besser lösen können.

    Dann kommt es halt darauf an, entweder man mag sich den Typ merken oder man löst es eleganter mit Templates würd ich mal sagen.


  • Mod

    Wortender schrieb:

    Dann kommt es halt darauf an, entweder man mag sich den Typ merken oder man löst es eleganter mit Templates würd ich mal sagen.

    Dann schreib doch mal bitte eine Liste aller möglicher Typen. Auch meiner, die ich gleich noch erfinde.



  • SeppJ schrieb:

    Wortender schrieb:

    Dann kommt es halt darauf an, entweder man mag sich den Typ merken oder man löst es eleganter mit Templates würd ich mal sagen.

    Dann schreib doch mal bitte eine Liste aller möglicher Typen. Auch meiner, die ich gleich noch erfinde.

    Dann baust du etwas ein, wovon du deine erfundenen Dinge dann ableitest.



  • SeppJ schrieb:

    Dann schreib doch mal bitte eine Liste aller möglicher Typen. Auch meiner, die ich gleich noch erfinde.

    Glaube das ist sogar ganz besonders garstig, weil es analog zu den reellen Zahlen so eine Liste nicht geben kann, denn hätten wir so eine (unendlich lange):

    struct { t_{1,1}; t_{1,2}; t_{1,3}; \dotsc };
    struct { t_{2,1}; t_{2,2}; t_{2,3}; \dotsc };
    struct { t_{3,1}; t_{3,2}; t_{3,3}; \dotsc };
    \vdots

    dann wär struct { u\_1; u\_2; u_3; \dotsc }; mit u_it_i,iu\_i \neq t\_{i,i} nicht drin. Oder überseh ich was? :p



  • wenn es nur endlich viele Grundtypen gibt, und jede struct nur endlich viele Members haben kann, gibt es aber nur abzählbar viele struct-Typen.


  • Mod

    Toll, dann schreibe ich also eine unfassbar lange Liste aller vorstellbaren struct-Typen. Oder ich benutze std::any. Welches davon sollte die "elegantere" Lösung sein?



  • SeppJ schrieb:

    Toll, dann schreibe ich also eine unfassbar lange Liste aller vorstellbaren struct-Typen.

    Du liest nicht zu. Wir haben SFINAE und Vererbung.

    Für können einzelne Typen vergemeinsamen und für jedes Derivat eine neue Funktion schreiben. Beispielsweise eine für Built-in-Typen und eine für deine erfundenen Dinge, die du von einem anderen Ding ableiten lässt, dass du auch da die Verallgemeinerung hast um mit Templates zu arbeiten.

    Dann müsste man den Rückgabetyp auch eigentlich nur noch in die Parameterliste einbauen und ein bisschen mit enable_if<> arbeiten.



  • Ich versteh den Einwand an der Stelle nicht. std::any bzw. ähnliche Konstrukte (boost::any ist langsam) sind an der Stelle völlig in Ordnung. Das ist halt "type erasure", das ist an sic schon nicht weniger elegant als SFINAE und erst recht nicht als Vererbung. Und immer wenn eine Framework irgendwelche Daten transportieren muss, wobei dem Framework selber völlig egal ist, was das für Daten sind, ist std::any eine absolut valide Lösung. Ich habe in dem Zusammenhang nicht über Vererbung oder Templates nachgedacht, aber ich geh stark davon aus, dass man z.B. in GUI Systemen nicht wirklich weit damit kommt. In den letzten Jahren habe ich vor allem mit Qt gearbeitet und in den Qt GUI Komponenten werden Daten als QVariant durchgereicht, das ist was ähnliches. Und mir fällt da auch keine andere elegante Lösung dafür ein.


  • Mod

    Finnegan schrieb:

    Oder überseh ich was? :p

    Ja. Kein struct-Typ kann unendlich viele Member haben. Das Diagonalargument funktioniert hier nicht.
    Kleines analoges Beispiel: Falls dein Argument funktionierte, müsste bereits die Menge der natürlichen Zahlen überabzählbar sei, die kann man ja auch in einer solchen Liste schreiben, wenn man die einzelnen Ziffern in umkehrter Reihenfolge notiert.



  • camper schrieb:

    Finnegan schrieb:

    Oder überseh ich was? :p

    Ja. Kein struct-Typ kann unendlich viele Member haben. Das Diagonalargument funktioniert hier nicht.
    Kleines analoges Beispiel: Falls dein Argument funktionierte, müsste bereits die Menge der natürlichen Zahlen überabzählbar sei, die kann man ja auch in einer solchen Liste schreiben, wenn man die einzelnen Ziffern in umkehrter Reihenfolge notiert.

    Jo, da war ich etwas vorschnell. Das funktioniert natürlich nur, wenn eine unendlich lange Konstruktion auch Teil der Menge ist.
    Bei den Nachkommastellen der reellen Zahlen funktioniert das - vor dem Komma und bei natürlichen Zahlen nicht, da es dort
    nur endlich viele Zifferen geben kann. Analog bei C++: Den konstruierten Widerspuchs-Typ kann es auch bei unendlichem Speicher
    nicht geben, da er nie vollständig sein kann (sonst wäre er ja ausdefiniert und damit endlich).



  • Jockelx schrieb:

    boost::any data(int column, int row);
    

    In einer Spalte kann ja ein string, in der nächsten ein double, usw... sein.
    Ist halt eine Möglichkeit das umzusetzen.

    Was passiert mit den Werten? Wer holt den string oder double da wieder heraus und woher weiß er, was da noch alles drin stecken könnte?


Log in to reply