2010-09-01 16 views
8

Có vấn đề gì với việc thực hiện đóng cửa như vậy (bị đánh cắp từ hack python) không?C + + đóng hack

void function(int value) { 
    struct closure { 
     closure(int v = value) : value_(value) {} 
     private: int value_; 
    }; 
    closure c; 
} 

Khi điều tra thêm, nó xuất hiện trong các hàm thành viên, biến cục bộ không thể được sử dụng làm giá trị mặc định, nhưng biến đối tượng có thể.

+0

Đó là những gì hầu hết các ngôn ngữ khác làm sau hậu trường khi bạn nắm bắt biến cục bộ có chức năng cục bộ. Ví dụ, dịch ngược mã C# bằng cách sử dụng các đại biểu ẩn danh và các biến bị bắt. –

+2

Bạn cần chuyển giá trị cho hàm tạo một cách rõ ràng: đối số mặc định của hàm không thể là biến cục bộ. Quy tắc đó dành cho các hàm _all_, không chỉ các hàm thành viên. –

+0

@ James, cảm ơn tôi không biết các quy tắc rất tốt – Anycorn

Trả lời

6

Điều đó có vẻ như là cơ sở tốt để đóng cửa. Nhiều thành ngữ hơn là hack, vì bạn hợp pháp sử dụng các tính năng ngôn ngữ cho mục đích dự định của chúng.

Tất nhiên, ví dụ của bạn không làm gì cả. Và nó chỉ có thể được sử dụng trong phạm vi function.

Cho không C++ 0x cắm:

#include <functional> 

void some_function(int x) { } 

void function(int value) { 
    struct closure { 
     std::function< void() > operator()(int value) 
      { return [=](){ some_function(value); }; } 
    }; 

    auto a = closure()(value); 
    auto b = closure()(5); 

    a(); 
    b(); 
    b(); 
} 
+0

đúng, tôi vừa đăng mẫu ngắn để đưa ra ý tưởng – Anycorn

+0

một trong những tháng này tôi đoán tôi cần bắt đầu sử dụng 0x – Anycorn

6

C++ tương đương với một kết thúc:

class Closure 
{ 
    public: 
     Closure(std::string const& g) 
      :greet(g) 
     {} 
     void operator()(std::string const& g2) 
     { 
      std::cout << greet << " " << g2; 
     } 
    private: 
     std::string greet; 
}; 

int main() 
{ 
    Closure c("Hello"); 

    c("World"); // C acts like a function with state. Whooo. 
} 

Với cú pháp lambda mới trong C++ 11 nó trở nên dễ dàng hơn.

int main() 
{ 
    std::string g("Hello"); 

    auto c = [g](std::string const& m) {std::cout << g << " " << m;}; 

    c("World"); 
} 

Với cú pháp lambda mở rộng mới trong C++ 14 (-std = C++ 1y trên gcc), việc này trở nên dễ dàng hơn.

int main() 
{ 
    auto c = [g="Hello"](std::string const& m) {std::cout << g << " " << m;}; 

    c("World"); 
} 
+0

Ví dụ dễ hiểu tuyệt vời, (+) – Wolf

+0

@Wolf: Cập nhật với C++ 11 –