2013-08-12 18 views
13

Il titolo dice praticamente tutto, come dovrei fare per simulare la corrispondenza di pattern in stile ML in C++, ad esempio;Simulazione della corrispondenza di pattern in stile ML in C++

Statement *stm; 
match(typeof(stm)) 
{ 
    case IfThen: ... 
    case IfThenElse: ... 
    case While: ... 
    ... 
} 

Dove 'IfThen', 'IfThenElse' e 'Mentre' sono classi che ereditano da 'Dichiarazione'

+0

Si potrebbe cercare il [modello visitatore] (http://en.wikipedia.org/wiki/Visitor_pattern) –

+2

Ho considerato il modello di visitatore, speravo in qualcosa di più elegante! – Skeen

+0

Uso giudizioso di qualcosa come Boost.Varianti e tuple possono simulare l'uso di tipi di dati algebrici. (Entrambe le varianti e le tuple in genere forniscono modi per decostruire i loro valori.) –

risposta

18

C'era una carta nel comitato di C++ di recente che descrivono una libreria che permette di fare proprio questo :

Aprire e ef fi ciente Tipo di interruttore per C++ da Stroustup, Dos Reis e Solodkyy
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3449.pdf

un link a una pagina con il codice sorgente:
01.235.https://parasol.tamu.edu/~yuriys/pm/

Disclaimer: Non ho provato a compilare o utilizzare questa libreria, ma sembra adattarsi alla tua domanda.

Ecco uno del campione fornito dalla libreria:

#include <utility> 
#include "match.hpp"    // Support for Match statement 

//------------------------------------------------------------------------------ 

typedef std::pair<double,double> loc; 

// An Algebraic Data Type implemented through inheritance 
struct Shape 
{ 
    virtual ~Shape() {} 
}; 

struct Circle : Shape 
{ 
    Circle(const loc& c, const double& r) : center(c), radius(r) {} 
    loc center; 
    double radius; 
}; 

struct Square : Shape 
{ 
    Square(const loc& c, const double& s) : upper_left(c), side(s) {} 
    loc upper_left; 
    double side; 
}; 

struct Triangle : Shape 
{ 
    Triangle(const loc& a, const loc& b, const loc& c) : first(a), second(b), third(c) {} 
    loc first; 
    loc second; 
    loc third; 
}; 

//------------------------------------------------------------------------------ 

loc point_within(const Shape* shape) 
{ 
    Match(shape) 
    { 
     Case(Circle) return matched->center; 
     Case(Square) return matched->upper_left; 
     Case(Triangle) return matched->first; 
     Otherwise() return loc(0,0); 
    } 
    EndMatch 
} 

int main() 
{ 
    point_within(new Triangle(loc(0,0),loc(1,0),loc(0,1))); 
    point_within(new Square(loc(1,0),1)); 
    point_within(new Circle(loc(0,0),1)); 
} 

Questo è sorprendentemente pulito!

L'interno della biblioteca sembra un po 'più spaventoso. Ho fatto una rapida occhiata e sembra che ci sia un bel po 'di macro avanzata e meta-programmazione.

+0

Questo è esattamente quello che stavo cercando :) – Skeen

+3

Nel caso in cui qualcun altro stia cercando la fonte di Mach7, è disponibile su github qui: https: // github. com/solodon4/Mach7 – Hiura

Problemi correlati