Lambda-Funktionen (sowie einige andere Arten von "aufrufbaren" Funktionen) können mithilfe der Vorlagenklasse std::function
, die sich im Header <functional>
befindet, eingepackt und gespeichert werden. Sein Template-Parameter ist eine Funktion Signatur mit der Syntax
ReturnType(ArgumentType1, ArgumentType2, ...)
so in Ihrem Fall die gesamte Funktion Wrapper wird
std::function<double(double)>
und damit Ihr Code wird
class MyClass
{
public:
inline double f(double x)
{
return _function(x);
}
void setFunction(std::function<double(double)> && f)
{
_function = f;
}
private:
std::function<double(double)> _function;
};
std::function
ist " mehr als ein Wrapper für Funktionszeiger. Wie Sie vielleicht wissen, können Lambda-Funktionen einen Teil des Variablenkontexts erfassen, der irgendwo gespeichert werden muss. std::function
macht das für Sie transparent.
Beachten Sie, dass std::function
überladene Signatur-/Vorlagenanrufoperatoren für Funktoren nicht unterstützt. Bei der Zuweisung eines Funktors mit einer Signatur eines Anrufers wie T operator()(T value)
zu einem std::function<double(double)>
kann dieser nur mit dieser Signatur aufgerufen werden. So gibt es keine std::function<T(T)>
(es sei denn, T
ist bereits bekannt, wie ein Template-Parameter Ihrer Klasse).
Eine Alternative, die in einigen Fällen effizienter sein könnten (Sie müssen es Benchmark/Profil), ist Ihre ganze Klasse ein Template-Klasse mit der Funktion Typ Parameter ist die Template-Parameter zu machen.Dann können Sie eine Funktion als Mitglied speichern:
template<typename Function>
class MyClass
{
public:
MyClass(Function && f) :
_function(f)
{}
inline double f(double x)
{
return _function(x);
}
private:
Function _function;
};
Um ein solches Objekt zu erstellen, müssen Sie die Template-Parameter angeben, wie folgt aus:
auto myLambda = [](double x){ return x * 0.25; };
MyClass<decltype(myLambda)> myObject { myLambda };
Um dieses hässliche syntaktischen Kopf zu vermeiden, fügen Sie eine „Hersteller“ -Funktion, die den Vorteil von Template-Typ Abzug nimmt:
template<typename Function>
auto makeMyClass(Function && f) -> MyClass<Function> {
return MyClass<Function>(f);
}
Dann wird der Code besser lesbar, mit der Verwendung von auto
wieder:
auto myLambda = [](double x){ return x * 0.25; };
auto myObject = makeMyClass(myLambda);
Es könnte alles sein, was ein einziges Doppel und ein Doppel nimmt. Sie könnten 'std :: function' verwenden. –
juanchopanza