Fragen zu Lambda-Ausdrücken
-
Was gibt es für Möglichkeiten, dass folgender Code kompiliert wird:
Linear Algebra.cpp
const double div = sqrt(s); matSA.map([div](double x) {return x / div;}); // Fehlermatrix.cpp
template <class T> void Matrix<T>::map(T (*func) (T)) {...}matSA ist vom Typ Matrix<double>. Wenn ich im Lambda-Ausdruck das div weglasse wird alles fehlerfrei kompliliert.
Es kommt btw folgender Fehler:
..\src\Linear Algebra.cpp: In Funktion »int main(int, const char**)«:
..\src\Linear Algebra.cpp:1582:46: Fehler: keine passende Funktion für Aufruf von »Matrix<double>::map(main(int, const char**)::<lambda(double)>)«
..\src\Linear Algebra.cpp:1582:46: Anmerkung: Kandidat ist:
In file included from ..\src\Linear Algebra.cpp:9:0:
..\src\matrix.h:136:8: Anmerkung: void Matrix<T>::map(T ()(T)) [with T = double]
..\src\matrix.h:136:8: Anmerkung: keine bekannte Umwandlung für Argument 1 von »main(int, const char**)::<lambda(double)>« nach »double ()(double)«
-
template<typename T, typename Callable> void Matrix<T>::map(Callable func);Wobei dir sicherlich bekannt ist, dass du Definition und Deklaration bei Templates nicht trennen kannst, sodass die Definition ebenfalls in den Header gehört.
-
Endlich ein Beitrag, in dem ich mitschreiben kann!
1. Zitiere ich mal den Standard:
N3337 5.1.2.6 schrieb:
The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const
conversion function to pointer to function having the same parameter and return types as the closure type’s
function call operator. The value returned by this conversion function shall be the address of a function
that, when invoked, has the same effect as invoking the closure type’s function call operator.Sprich: Du darfst kein Lambda-Capture haben. Hast du aber. Deswegen definiert der closure-Typ logischerweise keinen entsprechenden Konvertierungsoperator für den entsprechenden Zeigertyp (da der closure-Typ dann von scope-lokalen Variablen abhängig wäre).
2. Sobald du kein Lambda-Capture mehr hast, wäre der einzige Fehler eigentlich noch die Deduzierung. Gib einfach explizit
<double>als Template-Parameter an.Natürlich solltest du aber einfach Michels Variante nehmen.
-
Ok, damit wäre alles geklärt, thx.
Edit:
Ne, sry, es klappt doch noch nicht:in der matrix.h steht nun:
template<class T> class Matrix { public: //... template <class Callable> void map(Callable func); //... } //... template <class T, class Callable> void Matrix<T>::map(Callable func) { for (int i = 0; i < dim1_; i++) for (int j = 0; j < dim2_; j++) updateEntry(i, j, func(getEntry(i, j))); }Beim Kompilieren kommen folgende Fehler:
g++ -O2 -Wall -c -fmessage-length=0 -std=c++11 -o src\Statistik.o ..\src\Statistik.cpp
In file included from ..\src\Statistik.cpp:1:0:
..\src\matrix.h:626:34: Fehler: falsche Benutzung des unvollständigen Typs »class Matrix<T>«
In file included from ..\src\Statistik.cpp:1:0:
..\src\matrix.h:50:7: Fehler: Deklaration von »class Matrix<T>«
..\src\Statistik.cpp: In Funktion »statistik::Analysed statistik::analyse(Matrix<double>&, Matrix<double>&, long long int)«:
..\src\Statistik.cpp:178:20: Fehler: keine passende Funktion für Aufruf von »Matrix<double>::map(<unresolved overloaded function type>)«
..\src\Statistik.cpp:178:20: Anmerkung: Kandidat ist:
In file included from ..\src\Statistik.cpp:1:0:
..\src\matrix.h:137:8: Anmerkung: template<class Callable> void Matrix::map(Callable) [with Callable = Callable; T = double]
..\src\matrix.h:137:8: Anmerkung: Herleitung/Ersetzung von Templateargument gescheitert:
..\src\Statistik.cpp:178:20: Anmerkung: Template-Parameter »Callable« konnte nicht ermittelt werden
-
template <class T> template <class Callable> void Matrix<T>::map(Callable func) { ...Es geht um die Definition eines Membertemplates eines Templates; nicht um ein Template mit 2 Parametern.
Das verursacht vermutlich nicht den Fehler, den entsprechenden Code hast du aber nicht gezeigt.
-
Ja, mit Lambda-Ausdrücken funktioniert es jetzt, allerdings nicht mehr mit Funktionen vom Typ "T (*)(T)". In der statistik.cpp steht das hier:
erg.eigen.map(sqrt);erg.eigen ist vom Typ Matrix<double> und sqrt kommt aus cmath.
Die Fehlermeldung steht bereits in meinem letzten Beitrag.