Helpex - Trao đổi & giúp đỡ Đăng nhập
18

Tôi vừa mới bắt đầu học các hàm lambda trong C ++ và tôi không hiểu tại sao lambda chỉ cho phép chụp các biến lưu trữ tự động? Ví dụ:

int x;
int main() {
    [&x](int n){x = n;}; // 'x' cannot be captured...
    return 0;
}

Mặt khác, các biến tĩnh không cần chụp

static int s = 0;
[](int n){s = n;};

Vì vậy, tại sao ví dụ đầu tiên không được phép và ví dụ thứ hai hoạt động?

18 hữu ích 5 bình luận 13k xem chia sẻ
19

Bạn cần quay lại và tự hỏi: Tại sao lambdas lại nắm bắt các biến?

Lambdas có thể sử dụng các biến từ phạm vi bên ngoài. Tuy nhiên, nếu đó là các biến cục bộ, chúng sẽ vượt ra ngoài phạm vi và không thể được sử dụng sau khi hàm trả về. Nhưng một lambda có khả năng được gọi sau khi hàm trả về (lambda có thể được trả về từ hàm hoặc được lưu trữ trong một số biến toàn cục hoặc biến thể hiện, v.v.) và sau khi hàm trả về, nó không thể chỉ tham chiếu trực tiếp đến các biến cục bộ, bởi vì chúng không còn tồn tại nữa.

Đó là lý do tại sao lambda có thể nắm bắt các biến cục bộ bằng cách sao chép (sao chép giá trị của chúng tại thời điểm lambda được tạo). (Họ cũng có thể nắm bắt bằng cách tham chiếu, thay thế cho bản sao.)

Sự cố trên chỉ tồn tại đối với các biến của thời lượng lưu trữ tự động . Đối với các biến có thời lượng lưu trữ tĩnh (ví dụ: biến toàn cục, biến cục bộ tĩnh), chúng tồn tại suốt thời gian tồn tại của chương trình và không có vấn đề gì khi truy cập chúng bất cứ lúc nào.

19 hữu ích 3 bình luận chia sẻ
17

Bạn cần thay đổi phạm vi. Nhìn vào cái này:

int x = 4;

int main()
{
    cout << "::x = " << ::x << endl;

    [&](int a){ ::x = a; }(2);

    cout << "::x = " << ::x << endl;

    return 0;
}

Đầu ra:

::x = 4
::x = 2
17 hữu ích 4 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ c++ c++11 lambda , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading