Sie können die Tags zu einem Factory-Methode abzubilden;
%Vor% Die create_empty_value
Methode könnte dann wie folgt aussehen:
vereinfachte Version Live on Coliru
Wie kann ich diesen Code vereinfachen?
%Vor%Kurz gesagt,
mfer :: tag ist eine Enumeration, die wie enum tag {};
im Namespace mfer definiert ist.
mfer :: i_value ist eine abstrakte Klasse.
%Vor%mfer :: t_value ist wie eine Template-Klasse,
%Vor% In diesem Moment kann ich nicht this make_empty_value()
vereinfachen.
Idealerweise möchte ich es so machen:
%Vor%Aber ich weiß, dass es eine Vorlage ist, also macht oben kein Sinn.
Gibt es eine Idee, diesen Code zu vereinfachen? (Einige moderne C ++ - Funktionen, Boost-Bibliotheken und so weiter)
Mit ein wenig Template-Arbeit können wir die Factory-Funktion auf:
bringen %Vor%Vollständiger Code unten.
Die i_value-Generatorzuordnung wird zum Zeitpunkt der Kompilierung erstellt und ermöglicht das Nachschlagen bei konstanter Zeit.
Einschränkungen:
Die Werte in der Enumeration müssen fortlaufend sein, aber sie müssen nicht bei Null beginnen.
Diese Demo erfordert C ++ 14. Es kann leicht angepasst werden, um mit c ++ 11 zu arbeiten. Für c ++ 03 würden wir uns bemühen, mpl oder boost_pp zu verbessern.
vollständiges Arbeitsbeispiel:
%Vor%erwartete Ausgabe:
%Vor%Sie können die Tags zu einem Factory-Methode abzubilden;
%Vor% Die create_empty_value
Methode könnte dann wie folgt aussehen:
vereinfachte Version Live on Coliru
Sie können eine rekursive Template-Funktion erstellen, wenn der Enumerate-Wert einem bekannten Muster folgt (standardmäßig der nächste Enumerationswert gleich dem vorherigen Enumerate +1):
%Vor%Wenn Sie die konstitutive Regel Ihrer Aufzählung nicht kennen, können Sie das nicht tun (allgemeines konstitutives Gesetz ist wie in diesem Beispiel x [i + 1] = x [i] +1 oder x [i + 1] = x [i] & lt; & lt; 1 (linke Verschiebung).) Andernfalls ist es nicht möglich, über Elemente einer Aufzählung zu iterieren.
Hinweis: Die Funktion compute
wird sicherlich inline sein, aber im Zweifelsfall können Sie sie verwenden
Compiler-spezifisches Attribut als __forceinline
mit MSVC oder __attribute__((__always_inline__))
mit GCC oder clang.