2013-08-12 21 views
13

Der Titel sagt so ziemlich alles, wie würde ich gehen über ML-Muster-Matching in C++, das ist zum Beispiel;Simulieren ML-Stil Mustererkennung in C++

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

Wo IfThen ', ‚IfThenElse‘ und ‚While‘ sind Klassen, die von ‚Statement‘ erben

+0

Sie könnten nach dem [Besuchermuster] (http://en.wikipedia.org/wiki/Visitor_pattern) suchen –

+2

Ich habe das Besuchermuster betrachtet, hoffte auf etwas eleganteres! – Skeen

+0

Vernünftiger Einsatz von Boost.Variant und Tupeln kann die Verwendung von algebraischen Datentypen nachahmen. (Beide Varianten und Tupel bieten in der Regel Möglichkeiten, ihre Werte zu dekonstruieren.) –

Antwort

18

Es gibt ein Papier in der C-Komitee ++ war vor kurzem, die eine Bibliothek beschreiben, die genau das erlauben zu tun :

Öffnen und Ef fi zient Typ Switch für C++ von Stroustup, Dos Reis und Solodkyy
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3449.pdf

ein Link zu einer Seite mit Quellcode:

Haftungsausschluss: Ich habe nicht versucht, diese Bibliothek zu kompilieren oder zu verwenden, aber es scheint zu Ihrer Frage zu passen.

Hier ist einer der Probe von der Bibliothek zur Verfügung gestellt:

#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)); 
} 

Diese überraschend sauber ist!

Die Interna der Bibliothek sieht ein wenig erschreckender obwohl. Ich habe einen kurzen Blick darauf geworfen und es scheint eine ganze Menge fortgeschrittener Makro- und Meta-Programmierung zu geben.

+0

Dies ist genau das, was ich gesucht habe :) – Skeen

+3

Falls jemand anderes nach der Quelle von Mach7 sucht, ist es hier auf github verfügbar: https: // github. com/solodon4/Mach7 – Hiura