2013-07-24 42 views
8

Tôi quan tâm đến việc thực hiện lambda đệ quy, và tìm thấy mã này để tính Fibonacci:đệ quy lambda implemention trong C++ 11

std::function<int(int)> lfib = [&lfib](int n) {return n < 2 ? 1 : lfib(n-1) + lfib(n-2);}; 

Và tôi có một câu hỏi: std::function là một chức năng đa hình, vì vậy lfib tạo/và lưu lambda trong bộ nhớ heap, không phải trên stack. Và do đó có thể mất khả năng tối ưu hóa của chương trình. Đúng hay không?

+4

Có. Không chắc. –

+8

Đối với một chương trình có độ phức tạp thuật toán O (2^N), cơ chế của hàm gọi không quan trọng. – Cubbi

+0

Tôi đã không hỏi về việc thực hiện fibbonachi, tôi đã được hỏi về std :: chức năng có thể mất tối ưu hóa chương trình. –

Trả lời

5

Dữ liệu loại tẩy xóa là trạng thái std::function sẽ vẫn tồn tại miễn là std::function hoặc các bản sao của nó hoạt động, có thể thông qua phân bổ đống.

Điều tương tự cũng không đúng với việc đóng cửa, chứa các biến bị bắt. Đó là một phần của trạng thái của đối tượng lambda và có thể chứa địa chỉ của cấu trúc dữ liệu trên ngăn xếp, sẽ biến mất khi hàm hiện tại trả về và biến số lfib vượt quá phạm vi.

Hãy nhớ rằng bạn đã chụp lfib bằng cách tham chiếu. Do đó, bất kỳ thay đổi nào đối với lfib cho phần còn lại của hàm phải được hiển thị cho lambda (bao gồm nhưng không giới hạn đối với việc khởi tạo). Cách duy nhất mà trình biên dịch có thể quản lý theo cách tổng quát là lưu trữ địa chỉ của địa phương lfib. Trong trường hợp cụ thể của bạn, nếu lfib không được gán lại, trình biên dịch có thể lưu giá trị ngay sau khi khởi tạo thay vì tham chiếu. Nhưng nó không được đảm bảo, và thậm chí không có khả năng đặc biệt.

+1

Như vậy một lambda nhỏ có thể sẽ kết thúc trong Bộ đệm Nhỏ Tối ưu hóa và không gây ra bất kỳ phân bổ đống nào. – Xeo

+0

@Xeo: Khá có thể. Tôi không phải là chuyên gia về triển khai 'std :: function'. Điều quan tâm ở đây là cuộc đời. –

+0

@Xeo: không phải trong libstdC++, trong đó lambdas, vì một lý do nào đó, không bao giờ được lưu trữ trực tiếp trong 'std :: function', bởi vì chúng không được coi là" bất biến vị trí ". Xem 'std :: _ Function_base :: _ Base_manager :: __ saved_locally'. – Fanael