9 Stimmen

Automatisches Typ-Casting in C++: falsches Verhalten bei einer Container-Klasse

Ich implementiere einige Klassen für lineare Algebra-Operationen auf sehr kleinen Vektoren und Matrizen mit konstanter Größe. Currenty, wenn ich tun :

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} y Second = {2.3, 4.3, 6.3} , da das zweite Element vom Compiler in den ersten Elementtyp umgewandelt wird. Gibt es eine "einfache" Möglichkeit, die gleiche Art von automatischem Casting wie in nativem C++ anzubieten: int+double=double, double+int=double?

Ich danke Ihnen vielmals.

EDIT : Mit der in den Antworten angegebenen Syntax habe ich den Operator+ zum Laufen gebracht. Aber ich habe die folgende Syntax versucht, und die Kompilierung schlägt mit dem Fehler fehl: 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 mit dieser Syntax?

9voto

yuri kilochek Punkte 12292

使用する 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 Mitgliedsfunktion (im Körper der Klasse, wo T y s sichtbar sind):

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

5voto

Kerrek SB Punkte 445528

Verwenden Sie die std::common_type Trait, um den richtigen Ergebnistyp für eine gemischte Operation herauszufinden.

Die verlinkte Seite enthält sogar ein Beispiel, das Ihrem Fall sehr ähnlich ist.

4voto

ecatmur Punkte 145884

Unbedingt; 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 ist es vielleicht besser zu sagen, was Sie meinen, wenn Sie tatsächlich auf ein Vektor-Mitglied verweisen:

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>;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X