Lambda in statischem Array



  • Der Code ist aufs Notwendige reduziert. Fragen nach dem Sinn sind daher sinnlos.

    Daher, AFAICS, ist der Code in Ordnung.

    Ja, das hatte ich befürchtet. Sieht das hier noch jemand so? Oder kann vielleicht sogar jemand den Fehler in VS2012 nachvollziehen?

    Mit einer "normalen" Funktion statt eines Lambda-Ausdrucks tritt kein Fehler auf. Da ist wohl was faul im Compiler? Sieht aus wie ein Zugriff auf ein Objekt, das nicht mehr existiert. Und wohlgemerkt, nur im Debug-Build.



  • knivil schrieb:

    Was redest du da? Ich dachte, du kennst C++!

    Du machst mich schonwieder dumm von der Seite an ... Auf der einen Seite beschwerst du dich, auf der anderen biste selbst nicht besser ...

    Ja, aber das ist doch eine Frage, die du nicht fragen würdest. Ich wundere mich, ich mach dich ja nicht dumm an. Ich hätte meinen Daumen verwettet du wüsstest warum das geht. 😞
    (Natürlich bin ich nicht besser, es wäre ja lächerlich das zu suggerieren!)

    Also: War die Frage "ernst" gemeint?
    Wenn ja, ..hier ist der Standard...
    §8.5.3/5:

    A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:
    	[...] (trifft nicht zu)
    	-Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be const),
    		[...] (trifft nicht zu)
    		-Otherwise, a temporary of type “cv1 T1” is created and initialized from the initializer expression using the rules for a 
    		 non-reference copy-initialization (8.5). The reference is then bound to the temporary.
    

    function hat nun einen Konvertierungskonstruktor für nullptr_t , daher klappt das.

    Mal ehrlich, das weißt du doch...?

    Da ist wohl was faul im Compiler?

    👍

    ~Edit³: Es ist echt schwer, richtig den Standard zu zitieren... entweder die Einrückung stimmt nicht, oder ich kann Begriffe nicht kursiv machen o.ä.~



  • Ich dachte, du kennst C++!

    Soll ich das fuer dich sprachlich analysieren? .... es bedeutet soviel wie: anscheinend kannst du kein C++. Bzw. nur weil mir nicht jedes Detail C++ bekannt ist, unterstellst du mir Unfaehigkeit in C++. Was soll ich darauf nur antworten?



  • knivil schrieb:

    nur weil mir nicht jedes Detail C++ bekannt ist, unterstellst du mir Unfaehigkeit in C++.

    Das ist kein Detail, sondern praktisch Basiswissen. Mir fehlt es auch an viel Basiswissen, aber das ist bekannt.
    Ich hätte nicht erwartet, dass du plötzlich bei einem IMHO solch fundamentalen Punkt unwissend bist.

    Was soll ich darauf nur antworten?

    Nichts, war das denn eine Frage!? Ich hätte einfach erwartet, dass du dieses Detail kennst, das ist alles. War nur sehr überrascht. Ignorier' es einfach.



  • Da muss ich aber jetzt knivil eindeutig zustimmen, dass

    Was redest du da? Ich dachte, du kennst C++!

    sogar sehr dumme Anmache ist, das liest sich auch für mich als nichts als Provokation.
    Auch Aussagen wie

    was gibt es da zu erklären?

    sind absolut kontraproduktiv, Deine Erklärung war ja gut verständlich und hat sicherlich die Augen geöffnet (wobei, streng genommen mir nicht, aber egal), aber der Nachsatz nützt niemandem was.
    Hat natürlich nichts mit dem Rest des sonst informationsreichen Beitrags zu tun (jdf. klingt er so, ich kann es leider gerade nicht verifizieren). 😋



  • Das ist so, als würde jetzt Eisflamme fragen, wieso beim Überladen von operator<< eine Referenz auf ostream zurückgegeben wird. Das war jetzt ziemlich unerwartet.
    (Gut, der Post war auf den zweiten Blick sehr böse, das tut mir Leid.)

    wobei, streng genommen mir nicht, aber egal

    Du weißt es auch nicht!? Was zum... ?
    __________________________________________________________________________________________________________________________

    Sieht aus wie ein Zugriff auf ein Objekt, das nicht mehr existiert. Und wohlgemerkt, nur im Debug-Build.

    Merkwürdig.

    Da nichts gecaptured wurde, ist die Memberfunktion ja nicht von Membern des closure-Objektes abhängig, und daher geht es nicht um die Lebenszeit des closure-Objektes oder dessen Kopien... mit normalen Funktionen geht es. Nun, ein kryptischer Bug, würde ich vermuten. Sicher bin ich natürlich nicht.



  • Ich kannte den nullptr-ctor von std::function einfach nicht, etwas ähnliches wird wohl knivils Problem gewesen sein. Wozu gibt es den, wieso nicht einfach = UserFunc() ?



  • Eisflamme schrieb:

    Wozu gibt es den

    Keine Ahnung. Überall, wo man explizit nullptr zuweist, dass heißt keinen Nullzeiger, könnte man gleich den Initializer weglassen (oder im Falle eines Funktionsparameters eben wie du gezeigt hast).

    Edit: Wahrscheinlich, weil man beim Argument nullptr sonst diesen Konstruktor bekommt:

    template< class F > function(F);
    

    Schließlich sollte das Zuweisen von nullptr eigentlich möglich sein.

    Eine andere Begründung wäre, dass der nullptr_t -Konstruktor noexcept ist, der copy/move-Ctor allerdings nicht.

    Ich dachte, knivil wusste nicht, dass man einer const -Referenz zuweisen kann...



  • Eisflamme schrieb:

    Wozu gibt es den

    Wahrscheinlich zur Konsistenz mit Funktionszeigern: Intuitiv wird erwartet, dass Funktionszeiger (inklusive nullptr ) zu std::function konvertierbar sind.

    void (*fn)(int) = nullptr;
    std::function<void(int)> fn = nullptr;
    

    Sone schrieb:

    Ich dachte, knivil wusste nicht, dass man Temporaries einer const -Referenz zuweisen kann...

    Selbst dann wäre die Reaktion ziemlich arrogant. Zumal du selbst nicht selten mit ähnlichen Dingen auffällst... Sei bitte etwas zurückhaltender, sonst machst du dich nur unbeliebt.



  • Okay, bin ja schon still. Tut mir wie gesagt Leid.



  • Nexus:
    Ah, natürlich. Okay, das leuchtet ein, danke 🙂



  • Sone schrieb:

    Okay, bin ja schon still. Tut mir wie gesagt Leid.

    Entschuldigung gut. Merken & in Zukunft besser machen wäre noch besser 😉

    BTW: ich hab' da auch erstmal kurz doof geguckt. An implizite Konstruktoren denkt man nicht immer gleich, und wenn einem dann nicht gleich einfällt/auffällt dass std::function nen impliziten Ctor mit einem Funktionszeiger nullptr_t -Argument hat...

    Sowas nicht sofort zu sehen bedeutet nicht dass man kein Basiswissen hat. Ich kenne auch nicht viele C++ Programmierer persönlich von denen ich annehme dass sie aus der Zeile überhaupt irgendwann schlau geworden wären. Und ich kenne ein paar zig C++ Programmierer die mit C++ ihr Brot verdienen.

    ps: Ich weiss dass "tut mir Leid" in Wirklichkeit keine Entschuldigung ist. Aber ich interpretiere es mal so - weil's halt meistens so gemeint ist.

    ps2: Sieshte, ich hätte es nichtmal selbst gewusst 🙂 Wäre davon ausgegangen dass es nen Non-Template-Overload gibt der nen Funktionszeiger mit exakt passender Signatur nimmt.



  • Ich persönlich wusste, was diese Zeile macht, aber auch nur, weil ich gestern noch mir die Konstruktorenübersicht von std::function angesehen hattte.
    (Unnötiger, vom Themen ablenkender Beitrag, der nur mein Ego stärkt FTW!)



  • Ich denke ich sollte auch noch etwas dazu sagen. Ich wusste beisielsweise, dass nullptr in std::function umwandelbar ist. Jedoch wusste ich nicht, dass wenn eine Referenz verlangt wird, auch ein Umweg ueber implizite Konvertierung zu einem Objekt erlaubt ist, von dem dann die Referenz genommen wird. Dachte es sei nur ohne Umweg erlaubt.

    Ich weiss, dass ein temporaeres Objekt an const-Referenzen binden. Und ich weiss auch, dass einige Kompiler sich nicht daran halten.



  • void f(std::string const&);
    
    f("Aber du hast doch sicher schon hundert mal sowas hier gesehen?");
    

    Sowas nicht sofort zu sehen bedeutet nicht dass man kein Basiswissen hat. Ich kenne auch nicht viele C++ Programmierer persönlich von denen ich annehme dass sie aus der Zeile überhaupt irgendwann schlau geworden wären. Und ich kenne ein paar zig C++ Programmierer die mit C++ ihr Brot verdienen.

    Hier gibt es aber einen Widerspruch. knivil ist viel erfahrener und schlauer als ich. Hätte er gewusst, dass das so möglich wäre, aber nicht geahnt, dass function einen solchen Konstruktor hat, dann wäre das sehr merkwürdig. Daher musste ich darauf tippen, dass er das "Feature" nicht kennt. Und das war überraschend.



  • Sone...

    Als "fortgeschrittener Anfänger" der gerade alle Features von irgendwas "frisch" gelernt hat, verfällt man leicht in den Glauben, dass jeder alte Hase alles im Schlaf können/wissen muss was man selbst kann/weiss. Ganz speziell wenn man diese Irgendwas nicht als Mittel zum Zweck sieht, sondern sich aus Neugier und Spass an der Sache in alle Details vertieft.
    Dieser Glaube entspricht aber nicht der Realität. Zumindest nicht bei nicht-trivialen Dingen wie Programmieren.

    Und ganz speziell bei C++11 Features wirst du viele alte Hasen finden die nix oder nicht viel davon wissen. Ich hab' mir z.B. std::function auch nie wirklich angesehen. Ich kenne und verwende seit langem boost::function , und hab' mich einfach mit Aussage zufriedengegeben dass std::function im Prinzip das selbe wie boost::function ist. Verwendet hab' ich std::function selbst auch noch nie. Unsere Projekte sind allesamt ziemlich gross, und es wurde noch keines auf nen C++11-fähigen Compiler umgestellt. Wäre einiges an Arbeit. Und alle Verwendungen von boost::function durch std::function wäre dann nochmal extra Aufwand. Den halt keiner zahlt.


Anmelden zum Antworten