Info:Rückgabetyp der Template-Funktion
Ich versuche zur Zeit Metaprogrammierung zu lernen (von this book folgenden). Ein nützliches Beispiel, das sie geben, ist für die Dimensionsanalyse. Ich habe es wie im Buch umgesetzt und alles war in Ordnung; see here.
Mein Problem ist jedoch, ich möchte das dimensionale Analyse-Framework mit gemischten Typen verwenden. Damit meinen Sie, dass Sie einen Skalar mit Massenmaßen multiplizieren könnten, der einen Vektor mit Beschleunigungsdimensionen multipliziert, um eine Vektorkraft zu erhalten. Wie es im Link steht, arbeiten sie nur mit dem gleichen Typ T
für die Eingabe und Ausgabe aller Operationen.
Ich habe eine 3-Vektorklasse, die durch Skalare zur Multiplikation mit/Dividieren all notwendigen Operationen hat, etc., so würde ich so etwas wie
quantity<double,mass> m(1.0);
quantity<vect,acceleration> a(vect(0.0,0.0,-9.81));
quantity<vect,force> f = m*a;
Erster Versuch tun:
Um dies zu erreichen, habe ich versucht, die Beispiele aus dem Buch zu erweitern, um zwei verschiedene Typen als Eingaben für operator*
und operator/
zu behandeln, jedoch traf ich eine Wand, wenn es um den Rückgabetyp geht.
Ich weiß, hier der Rückgabetyp von double * vect
vect
ist, aber wenn sie in der anderen Richtung sind um vect * double
es ist immer noch ein vect
. Schlechter; im Prinzip könnte der Rückgabetyp alles sein. Deshalb möchte ich eine Möglichkeit, die operator*
zu so etwas wie
template<class T1, class T2, class Dim1, class Dim2>
quantity<X, typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
operator*(const quantity<T1,Dim1>& q1, const quantity<T2,Dim2>& q2)
{
return quantity<X,
typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
(q1.value()*q2.value());
}
auszudehnen, in denen X
ist der Rückgabetyp von q1.value()*q2.value()
und wird bei der Kompilierung abgeleitet. Ich versuchte, einfach eine weitere Vorlage Klasse T3
zu der Signatur hinzufügen und es T3
zurückgeben, aber es scheint, es kann nicht ableiten, was T3
sollte sein.
Zweiter Versuch:
Weiter habe ich versucht, mit decltype
wie
template<class T1, class T2>
struct return_type
{
auto mult_f(const T1& a, const T2& b)->decltype(a*b){return a*b;}
typedef decltype(mult_f) type;
};
template<class T1, class T2, class Dim1, class Dim2>
quantity<typename return_type<T1,T2>::type, typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
operator*(const quantity<T1,Dim1>& q1, const quantity<T2,Dim2>& q2)
{
return quantity<typename return_type<T1,T2>::type,
typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
(q1.value()*q2.value());
}
Doch diese eine Vielzahl von unverständlichen Compiler-Fehler führt.
Frage:
Meine Frage ist, dann bin ich decltype
in der richtigen Art und Weise verwenden, aber fehlen einige Syntax z.B. ein typename
Spezifizierer irgendwo? Oder; Ist das überhaupt möglich und wenn nicht, wie ist es möglich, den Rückgabetyp einer Funktion zu berechnen?
Danke.
Yeah, ich konnte aus der Compiler-Ausgabe, dass ich die ganze Funktion Signatur bekam sagen. Ich weiß nicht, warum ich die Dinge so kompliziert gemacht habe, dein Beispiel kompiliert gut :) Die Standard-Konstruktor-Anforderung ist für mich kein Problem. – Dan
@Dan: Beachten Sie, dass das Buch vor C++ 11 und 'declype' /' auto' Verfügbarkeit geschrieben wurde, was die Dinge ** viel ** komplizierter gemacht hat. –
Ersetzen Sie 'declltype (T1() * T2())' mit 'declltype (std :: declval() * std :: declval ())' und Sie benötigen keine Standard-Constructibility mehr. –
ildjarn