2013-05-27 8 views
6

Ich war ziemlich beeindruckt, das letzte Beispiel in Todd Veldhuizens zu sehen, in dem die trigonometrischen Funktionen sin und cos zur Kompilierungszeit vorberechnet sind. Um ehrlich zu sein, es hat mich umgehauen, und wenn Sie Code schreiben, der eine enorme Anzahl von diesen in Schleifen ausführt, wie ich bin, dann könnte dies eine wesentliche Auswirkung auf die gesteigerte Leistung haben.Welche mathematischen Operatoren sind in der Metaprogrammierung verfügbar?

Frage 1

aber es führte mich zu fragen, wo die Grenze zwischen gezogen, was als Laufzeitwerkzeug zur Verfügung steht (tatsächliche mathematische Bibliothek Funktionen wie sin oder cos Aufruf) und was ist als nur ein kompilierbarer mathematischer Operator.

Das Beispiel von Todd muss die trigonometrische Funktion manuell berechnen.

Bin ich dann davon ausgehen, dass ein Compiler von allen gewöhnlichen mathematischen Funktionen *+-/ aber sonst nichts fähig ist?

Frage 2

In einem solchen Fall würden Sie nur in der Lage sein zu bekommen Kompilierung-Ergebnisse für sin und cos Berechnungen auf ganze Zahlen, nicht wahr? Das heißt, Sie können das Ergebnis von etwa sin 45.5 nicht vorkompilieren, richtig?

Oder vielleicht, wenn die Vorlage nur ganze Zahlen als Parameter annehmen können, können Sie mehrere ganze Zahlen nehmen und ein float aus ihnen in der Klasse machen, wie vorbei 123 und 1.23 Herstellung der sin eines Float-Wert zu erhalten.

Antwort

2

Frage 1

aber es führte mich zu fragen, wo die Grenze zwischen gezogen, was als Laufzeitwerkzeug zur Verfügung steht (tatsächliche mathematische Bibliothek Funktionen wie sin oder cos Aufruf) und was ist als nur ein kompilierbarer mathematischer Operator.

  • Benannte Funktionen können nur bei compiletime verwendet werden, wenn sie constexpr deklariert sind, die Regeln der constexpr gehorchen und mit compiletime Konstanten bezeichnet.
  • Benutzerdefinierte Datentypen können nur dann zur Kompilierungszeit verwendet werden, wenn sie über constexpr Konstruktoren aus Compiletimekonstanten erstellt werden.
  • Jeder integrierte Operator, der auf Compiletime-Konstanten-Built-In-Typen arbeitet, ergibt eine Compiletime-Konstante.
  • Jede Typumwandlung zwischen Builtins ergibt eine Compiletime-Konstante, wenn das Original eine Compiletime-Konstante ist.

Also, es ist nicht auf die vier mathematischen Operatoren beschränkt, können Sie % und andere Betreiber als auch verwenden, sowie Vorlage Metafunktionen und constexpr Ausdrücke.

Frage 2

In einem solchen Fall würden Sie nur in der Lage sein, kompilieren Zeitergebnisse für die Sünde zu bekommen und cos Berechnungen auf ganze Zahlen, nicht wahr? Das heißt, Sie können das Ergebnis von etwas wie sine 45.5 nicht vorkompilieren, richtig?

Ja und nein. In C++ 03 sind Sie auf integrierte Metafunktionen und Vorlagen beschränkt, constexpr ist nicht verfügbar. Die sin muss daher eine Template-Metafunktion sein, die nur mit Integralkonstanten arbeiten kann, da Gleitkommatypen in Templates nicht erlaubt sind. Sie können jedoch Vorlagen für Bruchteile oder Festkommawerte definieren und dafür eine Vorlage sin erstellen. Das wäre jedoch ziemlich mühsam und Sie könnten leicht in Template-Instantiierungseinschränkungen geraten.

Seit C++ 11 können Sie constexpr Funktionen schreiben, die Gleitkommaparameter verwenden und mit diesen arbeiten.

+1

Zur Berechnung von Sinus in Kompilierzeit mit Serienerweiterung siehe http://www10.informatik.uni-erlangen.de/~pflaum/pflaum/ProSeminar/meta-art.html – jmihalicza

Verwandte Themen