2010-09-01 3 views
8

Y a-t-il un problème avec cette implémentation de fermeture (volée à partir de python hack)?Fermeture C++ hack

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

Après enquête, il apparaît dans les fonctions membres, les variables locales ne peuvent pas être utilisées comme valeurs par défaut, mais objet variables peuvent.

+0

C'est ce que font la plupart des autres langages en coulisses lorsque vous capturez une variable locale avec une fonction locale. Par exemple, décompilez le code C# en utilisant des délégués anonymes et des variables capturées. –

+2

Vous devez transmettre explicitement une valeur au constructeur: l'argument par défaut d'une fonction ne peut pas être une variable locale. Cette règle s'applique à toutes les fonctions, pas seulement aux fonctions membres. –

+0

@James, merci je ne connaissais pas très bien les règles – Anycorn

Répondre

6

Cela ressemble à une bonne base pour faire une fermeture. Plus d'un idiome que d'un hack, puisque vous utilisez légitimement les fonctionnalités du langage pour leur usage prévu.

Bien sûr, votre exemple ne fait rien. Et il ne peut être utilisé que dans function.

Gratuitous C++ 0x fiche:

#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

droite, je viens de poster un court échantillon pour donner l'idée – Anycorn

+0

un de ces mois, je suppose que je dois commencer à utiliser 0x – Anycorn

6

Le C++ équivalent d'une fermeture:

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

Avec la nouvelle syntaxe lambda en C++ 11 il devient encore plus facile.

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

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

    c("World"); 
} 

Avec la nouvelle syntaxe lambda étendue en C++ 14 (std = C++ gcc sur 1y), il devient encore plus facile.

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

    c("World"); 
} 
+0

Grand exemple facile à obtenir, (+) – Wolf

+0

@ Wolf: Mise à jour avec C++ 11 –