Antworten

Content

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:

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:

Und was können wir dann tun? Die Zeichenkette mit std::move in den Lambda-Ausdruck hineinschieben:

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.