Trong MATLAB, người ta có thể viết:Làm thế nào để "bỏ" một hàm hai đối số thành một hàm đối số?
S = @(x,y) x^2+y^2-1
G = @(x) S(x,1);
Nếu tôi có một chức năng hy vọng một chức năng một lập luận, tôi có thể làm các việc trên. Làm thế nào tôi có thể làm điều này trong c/c + +?
Tôi có chức năng thư viện (từ thư viện CGAL) dự kiến là đối số một hàm mà chính nó chỉ có một đối số. Lý tưởng nhất, tôi có một lớp (SphericalHarmonics
) và tôi muốn có một chức năng thành viên mà có một đối số. Vì vậy, tôi có:
FT SphericalHarmonics::distFunction(Point_3 p)
(lưu ý rằng FT
là một loại tương tự như double
) nhưng tất nhiên khi tôi cố gắng
SphericalHarmonics *sh = new SphericalHarmonics(1);
Surface_3 surface(sh->distFunction, Sphere(ORIGIN,2.));
this
cũng được coi là một cuộc tranh cãi, chức năng distFunction
của tôi là một hai chức năng đối số và lỗi được ném.
Lưu ý rằng điều này có thể được giải quyết với các biến toàn cục, ví dụ:
SphericalHarmonics *sh;
FT dist_function(Point_3 p) {
return sh->distFunction(p);
}
main() {
sh = new SphericalHarmonics(1);
Surface_3 surface(dist_function);
}
Tuy nhiên, điều này thực sự không phải là lý tưởng. Tôi muốn một cách để làm điều này mà không có biến toàn cầu, vì nó sẽ là tốt hơn để có thể có một hàm lớp dễ dàng tích hợp với thư viện CGAL.
Cảm ơn trước!
[CẬP NHẬT]
@ Andy-Prowl: Tôi đã thử std::bind
và lambda
bạn giải pháp, nhưng vẫn dường như đang chạy vào các lỗi liên quan đến số lượng các đối số.
Khi nào, trong main
, tôi sử dụng mã:
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.));
tôi nhận được lỗi:
~/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)’
và
~/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>)}’
và
~/CGAL-4.1/include/CGAL/Implicit_surface_3.h:34:9: note:
candidate expects 1 argument, 2 provided
[CẬP NHẬT]
Nó bây giờ đã rõ ràng với tôi rằng tôi cần một chức năng mà có thể được chuyển đổi sang một con trỏ hàm (ví dụ: surface
yêu cầu đối số con trỏ hàm). Quy tắc này đưa ra tùy chọn std::bind
. Hơn nữa, có vẻ như một lambda không thể được chuyển đổi thành một con trỏ hàm nếu nó nắm bắt các biến (capture-less vs. capturing lambdas). Vì vậy, tôi nghĩ câu trả lời của Andy-Prowl dưới đây nói chung là câu trả lời đúng cho câu hỏi này, mặc dù tôi sẽ cần phải tìm một công việc khác.
(Tôi đã không thực sự đọc câu hỏi) ràng buộc hoặc một lambda? –
Các thẻ gây hiểu lầm, nên chứa matlab/lambda – Dmitry
Có bất kỳ giải pháp nào trong số này thực sự hoạt động không? Không thể sử dụng liên kết để đứng trong con trỏ hàm? –