2014-04-15 6 views
6

Unter der Herrschaft von "es gibt nie etwas neues unter der Sonne", bezweifle ich, dass ich der erste Mensch bin, der diesen Trick entwickelt. Ich dachte, ich würde über etwas online stoßen, das es schließlich dokumentiert, aber ich habe noch nicht, also dachte ich, dass ich fragen würde.Hat dieses SFINAE-Muster einen Namen?

Zweck ist es, bestimmte Funktionen selektiv zu aktivieren, sofern sie relevant sind, ohne eine abgeleitete Klasse zu verwenden.

Gibt es einen Namen für dieses Muster? Und hat jemand nützliche Informationen zu diesem Muster oder einem Muster, das ähnlich funktioniert?

template<typename T, size_t N> 
class Point { 
public: 
    template<size_t P, typename T2=void> 
    using Enable2D = typename std::enable_if<P == 2 && N == P, T2>::type; 
    template<size_t P, typename T2=void> 
    using Enable3D = typename std::enable_if<P == 3 && N == P, T2>::type; 
    template<size_t P, typename T2=void> 
    using Enable4D = typename std::enable_if<P == 4 && N == P, T2>::type; 
    template<size_t P, typename T2=void> 
    using Enable2DOrHigher = typename std::enable_if<P >= 2 && N == P, T2>::type; 
    template<size_t P, typename T2=void> 
    using Enable3DOrHigher = typename std::enable_if<P >= 3 && N == P, T2>::type; 
    template<size_t P, typename T2=void> 
    using Enable4DOrHigher = typename std::enable_if<P >= 4 && N == P, T2>::type; 

    //Example use cases 
    template<size_t P=N> 
    static Enable2D<P, Point> withAngle(T angle, T magnitude = 1); 
    template<size_t P=N> 
    static Enable3D<P, Point> fromAngles(T psi, T theta, T magnitude = 1); 

    template<size_t P=N> 
    Enable2DOrHigher<P, T> const& x() const; 
    template<size_t P=N> 
    Enable2DOrHigher<P, T> const& y() const; 
    template<size_t P=N> 
    Enable2DOrHigher<P> setX(T const& t); 
    template<size_t P=N> 
    Enable2DOrHigher<P> setY(T const& t); 

    template<size_t P=N> 
    Enable3DOrHigher<P, T> const& z() const; 
    template<size_t P=N> 
    Enable3DOrHigher<P> setZ(T const& t); 

    template<size_t P=N> 
    Enable4DOrHigher<P, T> const& w() const; 
    template<size_t P=N> 
    Enable4DOrHigher<P> setW(T const& t); 
}; 
+0

Es ist eine interessante Idee - im Wesentlichen die Mitglied Funktionszeiger zu parametrisieren. In JavaScript können Sie das "Prototyp" -Objekt erstellen und dadurch bestimmte Elementfunktionen bedingt erstellen. Ich habe in C++ nichts Ähnliches gesehen. Neugierig, Antworten zu sehen ... –

+0

Der motivierende Anwendungsfall dafür war, dass wir auch mehrdimensionale Linien- und Kastenklassen hatten, die einen Standardpunkt nahmen, aber wir hatten vorher Klassen für Punkt2 und Punkt3 abgeleitet, also den nützlichen 2D- und 3D-Punkt Funktionen waren für die Klassen selbst nicht zugänglich (es sei denn, wir würden diese auch ableiten, in diesem Fall wäre es eine Neuimplementierung, da sich die Mitglieder geändert hätten und es eine Menge gemeinsamen Code gab, DRY), aber auch für jeden Code das verwendete die Box- und Linienalgorithmen. Wir waren der Ansicht, dass die Verwendung von SFINAE sauberer war, auch wenn die exponierten Funktionen etwas inkonsistent waren. – OmnipotentEntity

+0

Warum sollte die wiederholte Verwendung von 'enable_if' zu einem Muster werden? Dies ist eine typische Anwendung von 'enable_if' - z.B. Betrachten Sie [cppreference's description] (http://en.cppreference.com/w/cpp/types/enable_if) "* bedingt Funktionen und Klassen aus der Überladungsauflösung basierend auf Typeigenschaften entfernen und separate Funktionsüberlastungen und Spezialisierungen für verschiedene Typeigenschaften bereitstellen * "... scheint das, was Sie getan haben, völlig angemessen zu erfassen. –

Antwort

4

Ich würde es nicht ein Muster nennen, aber es ist eine bekannte Technik.

Meistens bezeichnet als bedingte Schnittstelle Diese Technik befasst sich hauptsächlich mit dem Problem eines Umschaltmechanismus zum Kompilieren, um Schnittstellen einer Klasse ein- und auszuschalten. Der Gesamtprozess stellt die Werkzeuge bereit, um auch die Existenz von Mitgliedern umzuschalten (so wird der Begriff bedingte Kompilierung geboren).

Die Technik ist mehr oder weniger implementiert, wie Sie vorschlagen (obwohl das Fehlen von Alias-Vorlagen kein Problem vor C++ 11 war) und das übliche Problem ist die schwere, unübersichtlich, verwirrend und "hässlich" Template-Maschine Mustercode.

Adressierung dieses Problems, A. Alexandrescugave a presentation über das Thema. Zunächst gibt es eine kleine Erwähnung der Bedarf für eine solche Technik:

enter image description here

Die Kugel, die

  • Diese Funktion sagt funktioniert nur mit Zahlen

auf Ihre Techniken reffering und die Notwendigkeit, Zeitbedingungen für die Kompilierung zu haben, um die Existenz von Funktionen umzuschalten (bedingte Schnittstelle).

Das Gespräch geht auf einen Vorschlag für eine neue Sprachfunktion. Da wir alle das Rad ein paar Mal erfunden haben, sagt er, warum nicht eine neue Sprachsyntax, die uns erlauben wird, solche Dinge zu tun. Seine joint work mit H. Sutter, produziert static if eine Kompilierzeit Toggler, die die Notwendigkeit für Umgehungslösungen als die Sie erwähnen würde. Eine einfache Verwendung davon wäre

template<int D> 
struct Vector 
{ 
    double coordinates[D]; 
    static if (D) { 
     double x() { return coordinates[0]; } 
    } 
    static if (D > 1) { 
     double y() { return coordinates[1]; } 
    } 
    static if (D > 2) { 
     double z() { return coordinates[2]; } 
    } 
}; 

OK vielleicht ist das nicht der intelligenteste Einsatz davon, aber ich denke, ich kommuniziere die Idee.

Auf der gegenüberliegenden Seite jetzt B. Stroustroup veröffentlichte ein paper wo nach den Problemen aknowledging static if Adressierung, erklärt er, warum es ein fehlerhaftes Konzept (Wortspiel beabsichtigt :)) und seine Annahme wäre eine Katastrophe für die seine Sprache (autsch!).

Das waren meine zwei Cent, nach dem Niveau der Teilnehmer in diesem "Gespräch" Ich hätte gerne ein Feedback darüber, auf welcher Seite sie stehen, oder ob sie Teil des Standardisierungsprozesses sind werden sie wählen?

+1

Ich weiß nicht viel Geschichte, aber vielleicht war es dann, dass Alexandrescu entschied, weiterzumachen und es [die D-Art] zu tun (http://dlang.org/cpptod.html#metatemplates) ... – iavr

Verwandte Themen