2012-07-31 4 views
9

Ich implementiere einige Klassen für lineare Algebra-Operationen auf sehr kleinen Vektor und Matrizen mit konstanter Größe. Currenty, wenn ich tun:C++ automatische Typumwandlung: falsches Verhalten für eine Container-Klasse

MyMathVector<int, 3> a ={1, 2, 3}; 
MyMathVector<double, 3> b ={1.3, 2.3, 3.3}; 
std::cout<<"First = "<<a+b<<std::endl; 
std::cout<<"Second = "<<b+a<<std::endl; 

Dann First = {2, 4, 6} und Second = {2.3, 4.3, 6.3}, da das zweite Element auf das erste Element Typ vom Compiler gegossen. Gibt es eine "einfache" Möglichkeit, die gleiche Art von automatischem Casting wie in nativem C++ bereitzustellen: int + double = double, double + int = double?

Vielen Dank.

EDIT: Mit der Syntax aus Antworten, bekam ich den Operator + arbeiten. Aber ich habe versucht die folgende Syntax und die Zusammenstellung nicht mit dem Fehler: expected a type, got ‘std::common_type<T, TRHS>::type’

#include <iostream> 
#include <type_traits> 

template<class T> class MyClass 
{ 
    public: 
     MyClass(const T& n) : _n(n) {;} 
     template<class TRHS> MyClass<typename std::common_type<T, TRHS>::type> myFunction(const MyClass<TRHS>& rhs) 
     { 
      return MyClass<std::common_type<T, TRHS>::type>(_n*2+rhs._n); 
     } 
     T _n; 
}; 

int main() 
{ 
    MyClass<double> a(3); 
    MyClass<int> b(5); 
    std::cout<<(a.myFunction(b))._n<<std::endl; 
} 

Was ist das Problem dieser Syntax?

Antwort

9

Verwenden std::common_type:

template <std::size_t s, typename L, typename R> 
MyMathVector<typename std::common_type<L, R>::type, s> operator+(MyMathVector<L, s> const& l, MyMathVector<R, s> const& r) 
{ 
    // do addition 
} 

Ot im Falle der Elementfunktion (in der Klasse Körper, wo T und s sichtbar sind):

template <typename TRHS> 
MyMathVector<typename std::common_type<T, TRHS>::type, s> operator+(MyMathVector<TRHS, s> const& rhs) const 
{ 
    // do addition 
} 
+0

Great! Für den Operator + funktioniert diese Syntax gut, aber sie stürzt für andere Funktionen ab, die ein Klassenmitglied sein müssen. Wie lautet die Syntax für eine Klassenmemberfunktion, wobei T der Klassentyp und TRHS der Typ des übergebenen Parameters ist? – Vincent

+0

@ Vincent bearbeitet Antwort entsprechend, anscheinend können Sie keine Code-Blöcke in Kommentaren setzen. –

+0

Vielen Dank. Ich habe die ursprüngliche Frage bearbeitet, weil ich den Syntaxfehler in dem bereitgestellten Stück Code nicht sehe ... – Vincent

5

Verwenden der std::common_type trait das herauszufinden Korrekter Ergebnistyp für einen gemischten Vorgang.

Die verknüpfte Seite hat sogar ein Beispiel, das Ihrem Fall sehr ähnlich ist.

4

Absolut; verwenden decltype:

template<typename Other> 
auto operator+(const MyMathVector<Other, size> &other) 
    -> MyMathVector<decltype(std::declval<T>() + std::declval<Other>()), size>; 

Als Nicht-Mitglied-Operator, könnte es besser sein zu sagen, was meinen Sie eigentlich ein Vektor-Mitglied Referenzierung:

template<typename size, typename L, typename R> 
auto operator+(const MyMathVector<L, size> &l, const MyMathVector<R, size> &r) 
    -> MyMathVector<decltype(l[0] + r[0]), size>; 
+0

Dies erfordert, dass "T" und "Other" öffentlich standardmäßig konstruierbar sind. Besser zu sagen 'std :: declval ()' usw. –

+1

@KerrekSB danke, behoben. – ecatmur

Verwandte Themen