VS und C++ Metaprogrammierung
-
Hallo!
Hoffe das meine Frage zu Visual Studio auch hier ok ist, statt im MFC-Forum.
Ich beschäftige mich momentan etwas mit Template Metaprogrammierung. Ich habe bei dem Codeschnipsel von Wikipedia allerdings Probleme diesen zu verwenden. Mit dem g++ kann ich diesen einwandtfrei kompilieren und linken und es kommen auch die erwarteten Ergebnisse heraus. Allerdings funktioniert der Code nicht mit Visual Studio 2005 und auch nicht mit Visual Studio 2003. Mit enums funktioniert alles, aber ich will ja nen double verwenden und kein long.Der Quellcode ist folgender:
#include <iostream> template<long B,unsigned long E> struct pow_helper { static const double value; }; template<long B,unsigned long E> const double pow_helper<B,E>::value=B*pow_helper<B,E-1>::value; template<long B> struct pow_helper<B,0> { static const double value; }; template<long B> const double pow_helper<B,0>::value=1; template<long B,long E> struct power { static const double value; }; template<long B,long E> const double power<B,E>::value= E<0 ? 1.0/pow_helper<B,E<0 ? -E : E>::value : pow_helper<B,E<0 ? -E : E>::value; int main() { std::cout << power<10,-3>::value << std::endl; }
Visual Studio kompiliert und linkt auch einwandtfrei. Bis zur Ausführung keine Probleme, allerdings bekomme ich bei den oben angegebenen Template-Parametern immer "1.#INF" ausgegeben. Er versucht 1.0 durch 0 zu teilen, denn wenn ich aus der negativen drei einer positive mache, kommt 0 raus. Wenn ich für den Exponenten 0 angebe, kommt wie gewünscht die 1, nur die Rekursion funktioniert nicht.
Muss man bei Visual Studio vielleicht besondere Einstellungen vornehmen oder kommt der einfach nur nicht mit dem Quellcode klar?
Danke schonmal im voraus!
Vellas
-
erster eindruck: du verwendest compiletime ausdrücke, allerdings mit double. imho werden compiletime ausdrücke nur mit integern per standard vorausgesetzt, dein bsp. basiert auf erweiterungen des gcc. egal, ich schau mal weiter.
-
Ich habe auch schon die double-Variablen probeweise auf long/int ungestellt, kommt aber trotzdem nicht das erwartete. Trotzdem danke schonmal.
Edit:
Habe in diesem Dokument Hoffmann Meta in Kapitel 5 gelesen das einige Compiler (nicht konkret welche) schnell an ihre grenzen Stoßen bei Metaprogrammierung mit Templates. Scheinbar bei VS der Fall, obwohl ich das sehr schade finde, ist eigentlich ein prima Compiler bzw. IDE. Für weitere Hinweise/Erklärungen/Link/whatever wäre ich trotzdem dankbar.
-
der compiler macht hier alles richtig. nicht jedes unerwartete verhalten ist ein bug - häufig ist das problem auch 30cm vor dem bildschirm
das problem hier ist, dass die initialisierer der klassenkonstanten keine konstanten arithmetischen ausdrücke sind. damit werden diese konstanten dynamisch initialisiert (nach der vorhergehenden zero-initialisierung). allerdings ist die reihenfolge der initialisierung hier unspezifiziert.Mit enums funktioniert alles, aber ich will ja nen double verwenden und kein long.
ein verständlicher wunsch, aber im zusammenhang mit templates zum scheitern verurteilt. es ist ja auch nicht möglich, float-konstanten als template paramter einzusetzen.
-
Danke camper!
camper schrieb:
damit werden diese konstanten dynamisch initialisiert (nach der vorhergehenden zero-initialisierung). allerdings ist die reihenfolge der initialisierung hier unspezifiziert.
Also (so verstehe ich das) kann die Zero-Initialisierung auch im nachhinein stattfinden wodurch das Ergebnis (Ausgabe von 0) zustande kommt.
-
Vellas schrieb:
Danke camper!
camper schrieb:
damit werden diese konstanten dynamisch initialisiert (nach der vorhergehenden zero-initialisierung). allerdings ist die reihenfolge der initialisierung hier unspezifiziert.
Also (so verstehe ich das) kann die Zero-Initialisierung auch im nachhinein stattfinden wodurch das Ergebnis (Ausgabe von 0) zustande kommt.
zero-intialisierung findet immer zuerst statt. allerdings dividierst du hier gelegentlich durch 0 (ergebnis ist unendlich), und bei manchen konstanten dividierst du dann entsprechend durch unendlich (ergebnis ist 0).
-
Okay, danke!