2010-09-01 9 views
8

Czy jest jakiś problem z taką implementacją zamknięcia (skradziony z Pythona hack)?C++ zamknięcie hack

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

Po dalszych badaniach, to pojawia się w funkcji składowych, zmienne lokalne nie mogą być wykorzystywane jako wartości domyślnych, ale sprzeciw zmienne mogą.

+0

To, co większość innych języków robi za kulisami, gdy przechwytujesz lokalną zmienną z lokalną funkcją. Na przykład dekompiluj kod C#, używając anonimowych delegatów i przechwyconych zmiennych. –

+2

Musisz jawnie przekazać wartość do konstruktora: domyślny argument funkcji nie może być zmienną lokalną. Ta zasada dotyczy wszystkich funkcji, a nie tylko funkcji składowych. –

+0

@ James, dziękuję Nie znałem reguł bardzo dobrze – Anycorn

Odpowiedz

6

To wygląda na dobrą podstawę do zamknięcia. Bardziej idiom niż hack, ponieważ zgodnie z prawem używasz funkcji językowych zgodnie z ich przeznaczeniem.

Oczywiście twój przykład nic nie robi. Można go używać tylko w zakresie od function.

Nieodpłatne C++ 0x wtyczki:

#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

prawo, właśnie wysłałem krótką próbkę, aby dać pomysł – Anycorn

+0

jeden z tych miesięcy Myślę, że muszę zacząć używać 0x – Anycorn

6

C++ równoważne zamknięcia:

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. 
} 

Dzięki nowej składni lambda C++ 11 staje się jeszcze prostsze.

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

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

    c("World"); 
} 

Dzięki długiemu lambda składni C++ 14 (-std = C++ 1 roku na GCC) staje się jeszcze prostsze.

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

    c("World"); 
} 
+0

Świetny łatwy do zdobycia przykład, (+) – Wolf

+0

@Wolf: Zaktualizowano C++ 11 –