2012-07-31 8 views
9

Sto implementando alcune classi per operazioni di algebra lineare su vettori e matrici di dimensioni molto piccole. Currenty, quando faccio:Trasmissione di tipo automatico in C++: comportamento errato per una classe contenitore

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; 

Poi First = {2, 4, 6} e Second = {2.3, 4.3, 6.3}, perché il secondo elemento è colato al primo tipo di elemento dal compilatore. C'è un modo "facile" per fornire lo stesso tipo di casting automatico come in C++ nativo: int + double = double, double + int = double?

Grazie mille.

MODIFICA: Con la sintassi fornita dalle risposte, ho ottenuto l'operatore + funzionante. Ma ho provato la seguente sintassi, e la compilazione fallisce con l'errore: 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; 
} 

Qual è il problema di che sintassi?

risposta

9

Uso 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 nel caso della funzione membro (nel corpo della classe, dove T e s sono visibili):

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

Grande! Per l'operatore + questa sintassi funziona bene ma si blocca per le altre funzioni che devono essere un membro della classe. Qual è la sintassi per una funzione membro della classe in cui T è il tipo di classe e TRHS è il tipo del parametro passato? – Vincent

+0

@Vincent modifica la risposta di conseguenza, apparentemente non è possibile inserire blocchi di codice nei commenti. –

+0

Grazie mille. Ho modificato la domanda originale perché non vedo l'errore di sintassi nella parte di codice fornita ... – Vincent

5

Utilizzare il std::common_type tratto di capire la tipo di risultato corretto per un'operazione mista.

La pagina collegata ha anche un esempio molto simile al tuo caso.

4

Assolutamente; utilizzare decltype:

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

In qualità di operatore terzo, potrebbe essere meglio dire cosa si intende per realtà riferimento a un membro di vettore:

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

Ciò richiede che 'T' e' Other' siano costruttivamente predefiniti. Meglio dire 'std :: declval ()' ecc. –

+1

@KerrekSB grazie, corretto. – ecatmur

Problemi correlati