========= Antworten [TOC] ========= Die Funktion `str_equivalence_ignore_case` weiß nichts über die Lebenszeit des Objekts, das wir per Referenz erhalten. Im konkreten Beispiel wird `"hallo"` übergeben, d.h. es wird ein temporäres Objekt erzeugt, das per Referenz übergeben wird. In dem Augenblick, in dem wir das Funktionsobjekt zurückgeben, existiert das temporäre Objekt nicht mehr und somit ist der Zugriff auf die Referenz aus dem Lambda-Ausdruck nicht wohldefiniert. Deswegen müssen wir die Zeichenkette kopieren: ---- CODE (type=cpp) ------------------------------------------------------- auto str_equivalence_ignore_case(const std::string& text) { return [=](const std::string& s) -> bool { return boost::iequals(s, text); }; } ---------------------------------------------------------------------------- Hätten wir das besser machen können? Ja, indem wir aus dem Parameter einen Werteparameter machen. Dann hat der Übersetzer je nach Aufruf zwei Möglichkeiten: * Wenn die zu übergebende Zeichenkette temporär ist, kann sie per _move constructor_ übergeben werden, d.h. in diesem Fall muss nicht kopiert werden. * Andernfalls ist das Kopieren unvermeidlich, aber dann haben wir einen lokalen Parameter, mit dem wir tun können, was wir wollen. Und was können wir dann tun? Die Zeichenkette mit `std::move` in den Lambda-Ausdruck hineinschieben: ---- CODE (type=cpp) ------------------------------------------------------- auto str_equivalence_ignore_case(std::string text) { return [t = std::move(text)](const std::string& s) -> bool { return boost::iequals(s, t); }; } ---------------------------------------------------------------------------- Zu beachten ist, dass dies erst ab C++14 unterstützt wird. Das bedeutet, dass wir im konkreten Beispiel das `std::string`-Objekt einmal konstruieren und anschließend nicht mehr kopieren, sondern nur per _move_ weitergeben. :navigate: up -> doc:index back -> doc:session06/page07 next -> doc:session06/page09