|
|
|
|
Répondre à mamiemando
|
Bonjour,
|
Bien que résolu je me permets de revenir sur le sujet car ce qu'à dit est faux (tu peux tout à fait implémenter * sur un vecteur), parce que tassin a dit un cas particulier de ce que j'ai donné, et parce que manifestement le code que je t'ai donné n'est pas clair.
#include <vector>
#include <ostream>
#include <iostream>
template <typename T1,typename T2>
std::vector<T2> operator*(const T1 & x,const std::vector<T2> & y){
const std::size_t n = y.size();
std::vector<T2> z(n);
for(std::size_t i=0;i<n;++i) z[i] = x * y[i];
return z;
}
template <typename T>
std::ostream & operator<<(std::ostream & out,const std::vector<T> & x){
const std::size_t n = x.size();
for(std::size_t i=0;i<n;++i) out << x[i] << ' ';
return out;
}
int main(){
std::cout << "vecteur v" << std::endl;
std::vector<int> v(5);
v[0] = 1; v[1] = 3; v[2] = 4; v[3] = 2; v[4] = 7;
std::cout << v << std::endl;
std::cout << (2*v) << std::endl;
std::cout << (3.1*v) << std::endl;
std::cout << "vecteur w" << std::endl;
std::vector<double> w(5);
w[0] = 1; w[1] = 3; w[2] = 4; w[3] = 2; w[4] = 7;
std::cout << w << std::endl;
std::cout << (2*w) << std::endl;
std::cout << (3.1*w) << std::endl;
return 0;
}
Donne a l'exécution : vecteur v 1 3 4 2 7 2 6 8 4 14 3 9 12 6 21 vecteur w 1 3 4 2 7 2 6 8 4 14 3.1 9.3 12.4 6.2 21.7 Ok revenons sur le code. On a définit un opérateur template * qui prend en membre de gauche un objet de type T1 et un vecteur sur T2 << qui prend un flux ouvert en écriture (dont std::cout et les std::ofstream) pour les vecteurs de type T Quelques rappels sur les templates Un type template peut être remplacé selon les besoins du compilateur par n'importe quel type. En l'occurrence no va compiler dans cet exemple : (1) Pour v: std::vector<int> operator*(const int & x,const std::vector<int> & y) (2) Pour w: std::vector<double> operator*(const int & x,const std::vector<double> & y) Si j'avais multiplié v (ou w) par un scalaire non entier (par exemple un float) j'aurais compilé des produits supplémentaires. Etant donné que le compilateur ne sait quels types vont remplacer les types template, et pour quels type il va devoir compiler une fonction, une fonction template est - soit implémentée dans un header inclu par chaque fichier source utilisant la fonction template - soit implémentée dans le fichier source qui sera le seul à pouvoir utilisé la fonction template Quel intérêt me direz vous ? Tout simplement, je n'écris qu'une fois le produit d'un vecteur par un scalaire et le compilateur sait directement de quoi je parle. Dans la méthode de Tassin (en admettant que Vector corresponde par exemple à typedef std::vector<int> Vector) le produit n'est défini que pour le produit d'un vecteur d'entiers par un flottant, ce qui est un peu dommage. Plutôt que d'écrire un opérateur à chaque fois que l'on manipule un type template, autant profiter de la puissance des templates. L'exemple en détail Pour v je calcule un vecteur produit d'entiers (voir opérateur (1)). Cela signifie que même si je multiplie le vecteur par un scalaire flottant, le vecteur calculé sera un entier (cf 3.1*v). C'est pourquoi on obtient seulement la partie entière. Pour w je calcul un vecteur produit de flottants (voir opérateur (2)), ce qui explique pourquoi j'obtiens bien le résultat auquel on s'attend, ie un vecteir de flottant J'insiste en particulier sur le fait que déclarer l'opérateur à l'extérieur de la classe revient à le déclarer à l'intérieur en tant que méthode (sauf que dans le premier cas on n'a pas accès aux membres protégés ou privés de la classe). Ainsi : #include <iostream>
class plop_t{
protected:
unsigned x;
public:
plop_t(unsigned x0):x(x0){}
unsigned get_x() const{
return x;
}
unsigned operator + (const unsigned y) const{
return x + y; // j'ai accès à x car je suis dans la classe
}
};
unsigned operator *(const plop_t & p,const unsigned y){
return p.get_x() * y; // je n'ai pas accès à x (protégé)
}
int main(){
plop_t p(69);
std::cout << (p + 1) << std::endl;
std::cout << (p * 2) << std::endl;
return 0;
}
marche et retourne bien : 70 138 Ainsi les opérateurs + et - ont été tantôt dans plop_t et tantôt dehors. Leur utilisation est cependant strictement similaire par la suite. En espérant que ce soit plus clair :-) Bonne chance |
Il ne faut pas que ce soit une méthode de ta classe Vector mais une fonction et une fonction friend de sucroit.
|
Ah ok je vois ce que tu veux dire. En fait tel qu'il a présenté son problème, je pensais qu'il recodait la classe Vector en cours de prog. Donc pour moi il partait de zero et n'utilisait pas la librarie standard (cf message 2).
|