Lambda in statischem Array
-
Okay, wenn ich ne Referenz benutze, warum sollte ich sie dann mit nullptr default initialisieren? Warum ueberhaupt default initialisieren? Warum kann ich nullptr einer Referenz zuweisen?
-
knivil schrieb:
const UserFunc& uvf = nullptrBitte erklaert mir das jemand.
Das nimmt den
nullptr-Konstruktor vonfunction- was gibt es da zu erklären?Das closure-Objekt ist kopierbar; Der Lambda-Ausdruck ist ein prvalue vom closure-Typ, welches kopiert wird (bzw. der Referenz im Konstruktor zugewiesen, die die Lebenszeit verlängert, und dann wird kopiert).
Daher, AFAICS, ist der Code in Ordnung.
P.S.: Das leere Klammerpaar kannst du weglassen.
[]{}Warum kann ich nullptr einer Referenz zuweisen?
Was redest du da? Ich dachte, du kennst C++!
Warum ueberhaupt default initialisieren?
Weil er ein default-Argument haben möchte?
-
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 ...
-
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.functionhat nun einen Konvertierungskonstruktor fürnullptr_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 wiewas 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 aufostreamzurü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
nullptrzuweist, 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
nullptrsonst diesen Konstruktor bekommt:template< class F > function(F);Schließlich sollte das Zuweisen von
nullptreigentlich möglich sein.Eine andere Begründung wäre, dass der
nullptr_t-Konstruktornoexceptist, 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) zustd::functionkonvertierbar 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::functionnen impliziten Ctor mit einemFunktionszeigernullptr_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
functioneinen 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::functionauch nie wirklich angesehen. Ich kenne und verwende seit langemboost::function, und hab' mich einfach mit Aussage zufriedengegeben dassstd::functionim Prinzip das selbe wieboost::functionist. Verwendet hab' ichstd::functionselbst 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 vonboost::functiondurchstd::functionwäre dann nochmal extra Aufwand. Den halt keiner zahlt.