2012-04-08 27 views
11

Tôi có mã này và không biết tôi có muốn đạt được điều gì không.Tôi có thể sử dụng hàm lambda trong chính nó như thế nào?

_acceptor.async_accept(
    _connections.back()->socket(), 
    [this](const boost::system::error_code& ec) 
    { 
     _connections.push_back(std::make_shared<TcpConnection>(_acceptor.get_io_service())); 
     _acceptor.async_accept(_connections.back()->socket(), this_lambda_function); 
    } 
); 

Khi ổ cắm được chấp nhận, tôi muốn sử dụng lại trình xử lý (còn gọi là hàm lambda). Điều này có thể không? Có cách nào tốt hơn để thực hiện việc này không?

+0

+1 Câu hỏi rất thú vị. Tôi đã không nghĩ về điều đó trước đây. – templatetypedef

+1

https://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/f1b3569c8aac0660?pli=1 – Anonymous

+0

Không liên quan đến câu hỏi của bạn, nhưng bạn nên biết rằng dấu gạch dưới hàng đầu (và hai dấu gạch dưới liền kề) được bảo lưu và không được sử dụng cho các số nhận dạng ứng dụng. – Marc

Trả lời

9

Bạn cần phải lưu trữ một bản sao của lambda trong chính nó, sử dụng std::function<> (hoặc một cái gì đó tương tự) như một trung gian:

std::function<void(const boost::system::error_code&)> func; 
func = [&func, this](const boost::system::error_code& ec) 
{ 
    _connections.push_back(std::make_shared<TcpConnection>(_acceptor.get_io_service())); 
    _acceptor.async_accept(_connections.back()->socket(), func); 
} 

_acceptor.async_accept(_connections.back()->socket(), func); 

Nhưng bạn chỉ có thể làm điều đó bằng cách tham khảo ; nếu bạn cố gắng nắm bắt nó theo giá trị, nó sẽ không hoạt động. Điều này có nghĩa là bạn phải hạn chế việc sử dụng một lambda như vậy để sử dụng được capture-by-reference sẽ có ý nghĩa. Vì vậy, nếu bạn rời khỏi phạm vi này trước khi chức năng async của bạn kết thúc, nó sẽ phá vỡ.

Phương án thay thế khác của bạn là tạo một hàm thích hợp thay vì một lambda. Cuối cùng, lambdas không thể làm mọi thứ.

+0

chúng ta không thể sử dụng 'auto'? – balki

+0

@balki: Không. Nó là hợp pháp trong C/C++ để khởi tạo một biến với một biểu thức sử dụng tên biến. Tuy nhiên, điều này được tắt khi xử lý các biến 'auto' vì tên biến không có loại cho đến khi loại biểu thức có thể được xác định. –

Các vấn đề liên quan