Bon, ok, je n'aurais pas du être aussi affirmatif C'est en tout cas la forme qui est recommandé par plusieurs références
Je pensais à ça http://books.google.fr/books?id=Qx5o...page&q&f=false
Sans mettre en doute ce propos, il appelle franchement à une explication/un example/un lien (le lien fourni ne donne pas d'explication sur ce point).
C'est un peu tiré par les cheveux car la multiplication matricielle pour des matrices non-carrées ne peut pas être faite "sur place". L'operator*= ne devrait pas être implémenté. D'ailleurs il ne peut pas l'être si la matrice est templatée sur sa taille (cas fréquent pour les petites matrices). Pour une utilisation normale, non-suprenante (en place) de operator@= la déclaration de mintho carmo me semble tout à fait juste.
Dans l'utilisation normale, on a besoin de l'ancienne valeur jusqu'au bout, ce n'est que dans des cas particuliers qu'il y a une séquence qui permette de modifier l'ancienne valeur sans la sauver en tout en en partie. Et encore plus particulier quand on peut composer l'ancienne valeur avec elle même... Une forme canonique doit fonctionner dans tous les cas, et pas être une optimisation parfois applicable.
Comme tu le mentionnes, @= ne pose pas de problème sur les matrices carrées (et mine de rien ça couvre quand même pas mal de cas d'utilisation)
Et même sur les autres, tu as effectivement un blocage si tu représentes la matrice M*N par un tableau statique bidimensionnel de M*N. Mais il y a nombre de représentation où tu peux implémenter @= sans souci problème.
Maintenant, si l'exemple de multiplication de matrice te pose problème, prends la multiplication de nombres complexes, le souci est le même (même s'il est largement plus simple à résoudre).
Le point est que dans nombres de cas tu as des membres où modifications et utilisations se chevauchent.
Je suis désolé mais je n'ai pas de lien* expliquant bien ceci. Par contre, tu peux en déduire que la RVO s'applique sur les types non référencés et comme += retourne une référence elle ne s'applique pas ici.
* Juste un exemple (operator+ en 1 ligne, operator- en 2)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 #include <iostream> struct A { A() = default; A(const A&) { std::cout << "copy\n"; } A(A&&) { std::cout << "move\n"; } }; A& operator += (A& a, A const & b) { return a; } A operator + (A a, A const & b) { return a += b ; } A& operator -= (A& a, A const & b) { return a; } A operator - (A a, A const & b) { a -= b ; return a; } int main() { A a; A b; { std::cout << "--------\n"; A c = a+b; std::cout << "--------\n"; } { std::cout << "--------\n"; A c = a-b; std::cout << "--------\n"; } }avec -fno-elide-constructors (pour désactivé la rvo)--------
copy
copy
--------
--------
copy
move
--------
--------
copy
copy
move
--------
--------
copy
move
move
--------
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager