in Matlab, si può scrivere:Come "trasmettere" una funzione a due argomenti in una funzione a un argomento?
S = @(x,y) x^2+y^2-1
G = @(x) S(x,1);
Se ho una funzione che si aspetta una funzione one-argomento, posso fare quanto sopra. Come posso farlo in c/C++?
Ho una funzione di libreria (dalla libreria CGAL) che prevede come argomento una funzione che ha esso stesso un solo argomento. Idealmente, ho una classe (SphericalHarmonics
) e vorrei avere una funzione membro che accetta l'argomento. Così ho:
FT SphericalHarmonics::distFunction(Point_3 p)
(si noti che FT
è un tipo simile a double
), ma naturalmente quando provo
SphericalHarmonics *sh = new SphericalHarmonics(1);
Surface_3 surface(sh->distFunction, Sphere(ORIGIN,2.));
this
viene trattato come argomento, la mia funzione distFunction
è un due argomento, e viene generato un errore.
noti che questo può essere risolto con variabili globali, cioè
SphericalHarmonics *sh;
FT dist_function(Point_3 p) {
return sh->distFunction(p);
}
main() {
sh = new SphericalHarmonics(1);
Surface_3 surface(dist_function);
}
Tuttavia, questo è davvero non ideale. Mi piacerebbe un modo per farlo senza variabili globali, dato che sarebbe molto meglio avere una funzione di classe che si integri facilmente con la libreria CGAL.
Grazie in anticipo!
[AGGIORNATO]
@ Andy-Prowl: ho provato le soluzioni di std::bind
e lambda
, ma sembrano ancora essere in esecuzione in errori per quanto riguarda il numero di argomenti.
Quando nel main
, io uso il codice:
SphericalHarmonics *sh = new SphericalHarmonics(cInit, numL, symm);
auto fxn = std::bind(&SphericalHarmonics::distFunction, sh, std::placeholders::_1);
Surface_3 surface(fxn, Sphere_3(ORIGIN,2.));
ottengo gli errori:
~/lib/basisfunctions/SphericalHarmonics2/mesh_an_implicit_function.cpp:62:48:
error: no matching function for call to
‘CGAL::Implicit_surface_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>,
double (*)
(CGAL::Point_3<CGAL::Epick>)>::Implicit_surface_3(std::_Bind<std::_Mem_fn
<double (SphericalHarmonics::*)(CGAL::Point_3<CGAL::Epick>)>
(SphericalHarmonics*, std::_Placeholder<1>)>&, Sphere_3)’
e
~/CGAL-4.1/include/CGAL/Implicit_surface_3.h:50:5: note: no known conversion
for argument 1 from ‘std::_Bind<std::_Mem_fn<double (SphericalHarmonics::*)
(CGAL::Point_3<CGAL::Epick>)>(SphericalHarmonics*, std::_Placeholder<1>)>’ to
‘CGAL::Implicit_surface_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>,
double (*)(CGAL::Point_3<CGAL::Epick>)>::Function
{aka double (*)(CGAL::Point_3<CGAL::Epick>)}’
e
~/CGAL-4.1/include/CGAL/Implicit_surface_3.h:34:9: note:
candidate expects 1 argument, 2 provided
[AGGIORNATO]
Ora è chiaro che ho bisogno di una funzione che può essere convertito in un puntatore alla funzione (cioè surface
richiesto un argomento puntatore di funzione). Questo esclude l'opzione std::bind
. Inoltre, sembra che un lambda non possa essere convertito in un puntatore a funzione se cattura le variabili (capture-less vs. capturing lambdas). Quindi penso che la risposta di Andy-Prowl qui sotto sia in generale la risposta corretta a questa domanda, anche se dovrò trovare un work-around diverso.
(non ho davvero leggere la domanda) si legano o un lambda? –
I tag sono fuorvianti, dovrebbero contenere matlab/lambda – Dmitry
Alcune di queste soluzioni funzionano davvero? Non è possibile utilizzare il bind per sostituire il puntatore alla funzione? –