templates: parameter mittels operatoren von nicht buildin-types ausrechnen?
-
also, nehmen wir mal an, ich habe eine klasse
template<int a> class INT{ };
man kann ja dieser klasse auf mehreren arten die template parameter übergeben, da währen:
INT<1> a; INT<1+2> a2; INT<int(1)+int(2)> a4;//nur zu anschauungszwecken //und noch einige mehr
nehmen wir mal an, ich wollte die Klasse INT so initialisieren:
INT<INT<5>()+INT<6>()>
wie müsste ich den operator+ in diesem fall überladen, damit er einen wert zurückgibt, der vom compiler akzeptiert wird?ps: würde diese implementierung des + operators in der INT Klasse irgendwelche zeit beim ausführen des programms einsparen?
template<int a> class INT{ public: template<int b> INT<a+b> operator+(INT<b> op){ return INT<a+b>(); } };
auch wenn dieser operator sehr unbeholfen aussieht, und mir einiges dran nicht gefällt, erzeugt er die gewünschte Klasse...
-
template<int A> struct INT{ operator int(){ return A; } }; template<int A,int B> INT<A+B> operator+(INT<A>,INT<B>){ return INT<A+B>(); } template<int A,int B> INT<A*B> operator*(INT<A>,INT<B>){ return INT<A*B>(); } int main(){ cout<< INT<3>()+INT<2>()*INT<2>() ;
-
soweit war ich in etwa ja auch schon, sieht man ja an meinem letzten op, es ging jetzt eigentlich nurnoch darum, noch so einen ausdruck erzeugen zu können:
INT<INT<5>()+INT<6>() > a;
ich bekomm nämlich immer den error dass er nur einen konstanten ausdruck akzeptiert, aber eigentlich ist dieser ausdruck ja konstant, und ich frage mich, ob man dem compiler klarmachen kann, dass dieser ausdruck _konstant_ ist.
-
da wirst du wohl um sowas in der art nicht herumkommen:
template <int A> struct INT { operator int () const { return A; } static const int value = A; }; template <class T, class U> struct PLUS { static const int value = T::value + U::value; }; int main(){ cout << INT<PLUS<INT<2>,INT<3> >::value>() << endl; //bzw. cout << INT<PLUS<INT<2>,INT<3> >::value>::value << endl; //bzw. cout << INT<INT<2>::value + INT<3>::value>() << endl; }
-
hmm, irgendwo, ich glaub in nem artikel bei blitz++, hab ich auch mal nen template ausdruck mit expr<(a+1/(a+2))> gelesen...hmm muss da nochmal reinschaun
-
hmm hab mir das nochmal so durch kopf gehen lassen...
ich versteh nicht, wieso der compiler beiINT<INT<5>()+INT<6>() > a;
erstmal meckert, weil es eine invalid template argument list ist,und wenn man dann klammern drumsetzt
INT<(INT<5>()+INT<6>()) > a;
sagt, dass es nicht konstant ist...aber wieso ist dann
INT<int(1)+int(2)> a; konstant? was ist da anders?
-
Die template-Wertargumente müssen (genau wie Arraygrößen) schon zur Kompilierungszeit feststehen, und in deinem Fall müsste ein Compiler schon inlinen, damit er es überhaupt kompilieren kann. So als praktische Begründung
(Für die genauen Regeln, was erlaubt ist, kannst du nach integral constant expressions suchen.)
(Editieren macht Spaß.)
-
operator void schrieb:
und in deinem Fall müsste ein Compiler schon inlinen, damit er es überhaupt kompilieren kann
Ich glaube, dass nicht mal das funktionieren würde. Imo sind es keine gültigen Template Parameter, wenn ich den Standard da richtig verstehe.
Non-type Template Parameter:
- integral or enumeration type
- pointer to object or pointer to function
- reference to object or reference to function
- pointer to member
-
referenzen auf funktionen? gibts das überhaupt?
//edit hier stand mist^^
-
otze schrieb:
referenzen auf funktionen? gibts das überhaupt?
klar - nur habe ich noch nie ne sinnvolle Anwendung dafür gefunden...
-
Bei Funktionen, die einen Callback erwarten, kann man damit sagen, dass man nicht 0 haben will - macht nur keiner. (Und echte Männer nehmen eh boost::function.)