PDA

Visualizza la versione completa : [C++] Templates multipli


RooccoXXI
19-08-2012, 12:06
Ciao. Scusate il titolo, ma non sapevo che altro scrivere: mi spiego subito. Ho creato un template di classe che rappresenta delle matrici. Tutto ok, finché non ho testato le seguenti linee di codice:


Matrix<double> m1(3,3,1.); // Matrice 3x3 piena di 1.

std::cout << 3. * m1 << std::endl; // Funziona (vedi ridefinizione dell'operatore *)
std::cout << 3 * m1 << std::endl; // Non funziona (3 é int e non double)


Per gli operatori esterni sono riuscito a risolvere utilizzando due parametri template. Ma per quelli esterni come fare? Vorrei chiaramente abilitare tutte le possibili combinazioni di tipi (visto che la classe funziona solo con tipi aritmetici): ha perfettamente senso sommare una matrice di int a una di double o una di std::complex a una di double o di int.

Ps: Dubbio: std::complex é aritmetico, giusto?

Grazie,
R.

RooccoXXI
21-08-2012, 12:15
UP

shodan
21-08-2012, 12:47
Originariamente inviato da RooccoXXI
ha perfettamente senso sommare una matrice di int a una di double o una di std::complex a una di double o di int.

Dipende. Se sommi una matrice di double a una matrice di int ottieni una matrice di double, idem se la moltiplichi. Se invece sommi o moltiplichi) una matrice di int a una di double rimarrai con una matrice di double. E lo stesso vale con std::complex.
Per farla breve con gli operatori che hai definito puoi solo operare su tipi omogenei.
Se vuoi operare con tipi non omogenei è necessario usare un altro sistema (metaprogrammazione template).
E' quello che ti avevo accennato tempo fa.

std::complex ha operatori matematici, ma non rientra nei tipi riconosciuti da std::is_arithmetic<>. Tuttavia è possibile farlo digerire allo static_assert usando un apposito traits:




template <typename T>
struct is_complex : public std::false_type {};

template <typename T>
struct is_complex<std::complex<T>> : public std::true_type {};

static_assert(std::is_arithmetic<T>::value || is_complex<T>::value, "");

RooccoXXI
22-08-2012, 23:02
Originariamente inviato da shodan
Dipende. Se sommi una matrice di double a una matrice di int ottieni una matrice di double, idem se la moltiplichi. Se invece sommi o moltiplichi) una matrice di int a una di double rimarrai con una matrice di double. E lo stesso vale con std::complex.
Per farla breve con gli operatori che hai definito puoi solo operare su tipi omogenei.
Se vuoi operare con tipi non omogenei è necessario usare un altro sistema (metaprogrammazione template).
E' quello che ti avevo accennato tempo fa.


È proprio il problema che ho incontrato. Anche utilizzando due parametri template, quello restituito definisce il tipo. Quindi il tipo é definito dalla posizione rispetto all'operatore e non dal tipo con meno perdita di informazione.

Puoi indicarmi qualche buona referenza su dove posso almeno capire i rudimenti della metaprogrammazione template? ;)

Grazie ancora per l'aiuto.

Ps: Per i tipi omogenei la classe sembra funzionare alla grande! ;)

shodan
22-08-2012, 23:44
Puoi indicarmi qualche buona referenza su dove posso almeno capire i rudimenti della metaprogrammazione template?

E' un argomento a cui hanno dedicato un libro perché non è proprio facilissimo:
http://www.amazon.com/Template-Metaprogramming-Concepts-Techniques-Beyond/dp/0321227255

altrimenti vediti un po' di questi link.
https://www.google.it/search?q=template+metaprogramming+c%2B%2B&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:it:official&client=firefox-a

Al di la di questo, gli operatori matematici disomogenei non puoi implementarli come membri della classe, ma come funzioni a se stanti (scordandosi la friendship per non impazzire con i prototipi).

RooccoXXI
23-08-2012, 02:30
Originariamente inviato da shodan
E' un argomento a cui hanno dedicato un libro perché non è proprio facilissimo:
http://www.amazon.com/Template-Metaprogramming-Concepts-Techniques-Beyond/dp/0321227255

altrimenti vediti un po' di questi link.
https://www.google.it/search?q=template+metaprogramming+c%2B%2B&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:it:official&client=firefox-a

Al di la di questo, gli operatori matematici disomogenei non puoi implementarli come membri della classe, ma come funzioni a se stanti (scordandosi la friendship per non impazzire con i prototipi).

Mmmh. Opto per i link perché ho solo 10 giorni per affrontare l'argomento (vacanze e poi si ricomincia scuola). Magari il libro sarà per l'estate. ; ). Grazie comunque.

Immaginavo che avessero scritto un libro a parte, perché nei libri di base non viene nemmeno accennato. Comunque la classe per ora funziona visto che per ora la uso io conosco le sue limitazioni e quindi va bene lo stesso.

Sai in che linguaggio é scritto MATLAB? ;)

Loading