Wenn Sie nach Wert übergeben, kopieren Sie das Closure-Objekt (vorausgesetzt, Sie definieren das Lambda nicht inline, in diesem Fall wird es verschoben). Dies kann unerwünscht sein, wenn der Zustand teuer zu kopieren ist, und wird nicht kompiliert, wenn der Zustand nicht kopierbar ist.
template <class Function>
void higherOrderFunction(Function f);
std::unique_ptr<int> p;
auto l = [p = std::move(p)] {}; // C++14 lambda with init capture
higherOrderFunction(l); // doesn't compile because l is non-copyable
// due to unique_ptr member
higherOrderFunction([p = std::move(p)] {}); // this still works, the closure object is moved
Wenn Sie mit dem const
Verweis übergeben, dann können Sie keine mutable
Lambda übergeben, die ihre Datenelemente als Argument für higherOrderFunction()
ändert, weil ein mutable
Lambda eine nicht const
operator()
hat, und Sie können nicht, dass const
auf eine aufrufen Objekt.
template <class Function>
void higherOrderFunction(Function const& f);
int i = 0;
higherOrderFunction([=]() mutable { i = 0; }); // will not compile
Die beste Option ist die Verwendung einer Weiterleitungsreferenz. Dann kann higherOrderFunction
entweder lvalues oder rvalues akzeptieren, die der Anrufer übergibt.
template <class Function>
void higherOrderFunction(Function&& f) {
std::forward<Function>(f)();
}
Dies ermöglicht die einfache Fälle sowie die oben genannten zu kompilieren. Für eine Diskussion, warum std::forward
verwendet werden sollte, siehe this answer.
Live demo
Ich glaube, das kopiert nicht, aber bewegen. Sollte mit einer anständigen Implementierung schnell genug sein. Lambdas sind so konzipiert, dass sie von einem solchen Wert weitergegeben werden - alle Standardalgorithmen nehmen ihre Funktoren wert. –