Tôi đang cố gắng chuyển một lambda tùy chỉnh cho một hàm mong đợi một con trỏ hàm (chính xác hơn là không
TRONG thư viện Brent chức năng).
Ý tưởng của mình là sẽ tạo lambda một lần với các tham số rồi đánh giá nó bằng nhiều giá trị x
bên trong chức năng này.
Tôi đã thử cái này chủ đề Các bước thực hiện không thành công và tôi nhận được lỗi không có chuyển đổi nào được biết đến cho đối số 4 từ 'Hàm {aka std::function}' thành 'double (*)(double)'
.Theo tôi hiểu thì trình biên dịch không biết cách chuyển đổi từ hai loại này.
Có cách giải quyết nào cho lỗi này không? Sẽ tốt hơn nếu tôi không phải thực hiện bất kỳ sửa đổi nào đối với thư viện và có thể giải quyết nó trong chương trình của mình. Đây là đoạn mã hiển thị vấn đề.
# bao gồm
# bao gồm "brent.hpp"
sử dụng không gian tên brent;
typedef std::function Hàm;
Hàm function_builder (double a, double b)
{
trả về [a,b](double x) {
trả về (a * x + b);
};
}
int chính ( )
{
Hàm func = function_builder(2.0, -1.0);
double z = zero (0, 1, 0.001, func ); //func phải là con trỏ hàm kiểu double (*)(double)
trả về 0;
}
Trong trường hợp của bạn, hàm lambda của bạn có trạng thái - các biến a, b được ghi lại. Không có cách nào để chuyển đổi lambda trạng thái thành con trỏ thành hàm, nhưng...
thư viện BrentCon trỏ tới chức năng không được mong đợi. không
Hàm được khai báo là:
double zero (double a, double b, double t, func_base& f )
Và có một tình trạng quá tải được định nghĩa là:
// Đây là tình trạng quá tải mà bạn đã hỏi, nhưng....
kép số không (double a, double b, double t, double f (double x) ){
func_wrapper foo(f);
trả về 0(a, b, t, foo);
}
Nhưng bạn nên sử dụng biến thể đầu tiên nếu cần, nó mong đợi:
lớp func_base{
công cộng:
toán tử kép ảo() (double) = 0;
};
Đây là tin tốt vì bạn vừa lấy được từ func_base và đặt lambda vào đó:
mẫu
lớp FunctionWithState : public func_base, public Lambda {
công cộng:
FunctionWithState(const Lambda & lambda): Lambda(lambda) {}
ghi đè toán tử kép()(double x)
{ trả về Lambda::operator()(x);
};
mẫu
chức năng tự động_builder_base (Lambda lambda)
{
trả về FunctionWithState(lambda);
}
auto function_builder(double a, double b)
{
trả về function_builder_base([a,b](double x) {
trả về (a * x + b);
});
}
Chi tiết triển khai hơi xấu, nhưng cách sử dụng thì hợp lý:
chủ yếu ( )
{
// func phải là "auto" vì loại phụ thuộc vào lambda, loại không xác định.
auto func = function_builder (2.0, -1.0);
gấp đôi z = 0 (0, 1, 0,001, func );
trả về 0;
}
Tất nhiên, có thể loại bỏ hoàn toàn các hàm lambda và quản lý trạng thái trong các đối tượng không có khuôn mẫu. Nhưng mặt khác, việc kế thừa từ lambda giúp dễ dàng định nghĩa nhiều hàm builder khác, chẳng hạn như:
auto function_builder3(double a, double b, double c)
{
trả về function_builder_base([a,b,c](double x) {
trả về (a*x*x + b*x + c);
});
}
Trên thực tế, bạn có thể sử dụng nó trực tiếp ở bất cứ đâuhàm_builder_base
, bỏ quahàm_builder
người trung gian.
Tôi là một lập trình viên xuất sắc, rất giỏi!