OVH Cloud OVH Cloud

[Vider un std::vector] swap

32 réponses
Avatar
Fabien LE LEZ
Bonjour,

J'aimerais savoir s'il y a une différence entre

vector<C> v;
...
vector<C>().swap (v);

et

vector<C> v;
...
v.swap (vector<C>());

Merci d'avance...


--
schtroumpf schtroumpf
Jean-Emile de France

10 réponses

1 2 3 4
Avatar
Gabriel Dos Reis
drkm writes:

[...]

| C'est marrant. Je savais, en écrivznt l'article auquel a répondu
| Gaby, que j'aurais du préciser ce que je voulais dire. Je sais que
| swap() prend une référence non constante, et que donc je dois
| m'attendre à ce que son paramètre soit modifié.

Je sais que tu le savais, c'est pour cela que je n'ai pas mentionné
« référence non-const ».

| Mais je trouve tout de même que lorsque l'on a un objet A a
| modifier, et un objet B créé pour le modifier, plus clair d'écrire
|
| A.swap( B ) ;
|
| que
|
| B.swap( A ) ;

Mais, ils se modifient l'un et l'autre ! :-)

Il y a une légende urbaine assez persistante (bien que fausse) selon
laquelle C++ serait un langage orienté objet -- avec le corollaire que
tout serait dans la syntaxe. Cette légende a fait beaucoup de ravages
et va continuer à en faire pendant un bon moment :-(

C++ *supporte* la programmation orientée, ainsi que d'autres
philosophies de programmation. La distinction est tout
n'est pas OO en C++, en particulier ce n'est pas parce que tu utilises
une syntaxe pour écrire « OO » que dès que tu vois cette syntaxe,
quelqu'un a écrit « OO ». De fait, la STL n'est pas OO. Alors, les
raisonnomentss du genre « c'est pas naturel selon la syntaxe OO » n'ont
pas grand sens. La question serait plutôt « est-ce que c'est du C++
idiomatique ». La réponse est oui.

Comment vider la poubelle de « v » ? La construction idiomatique est

(1) prends une poubelle vide -- vector<T>()
(2) échange-la avec celle de v -- .swap(v)

Le tout donne « vector<T>().swap(v) »

| Je m'attend plus à ce qu'un objet soit modifié par le message qu'on
| lui envoit que le paramètre soit modifié par le message dont il est le
| paramètre.

t'as pas encore été corrompu par les apôtres OO des getters ? ;-)

-- Gaby
Avatar
drkm
drkm writes:

Je m'attend plus à ce qu'un objet soit modifié par le message qu'on
lui envoit que le paramètre soit modifié par le message dont il est le
paramètre.


Mais 1/ je sais que cela est subjectif et 2/ non, je n'avais pas vu
ton ";-)".

:-$

--drkm

Avatar
Vincent Lascaux
| Mais je trouve tout de même que lorsque l'on a un objet A a
| modifier, et un objet B créé pour le modifier, plus clair d'écrire
|
| A.swap( B ) ;
|
| que
|
| B.swap( A ) ;

Mais, ils se modifient l'un et l'autre ! :-)


Et c'est bien pour ca (comme on est tous d'accord que les deux écritures
sont équivalentes) qu'on se demande laquelle des deux est la plus lisible
(et c'est pas la peine de répondre "Mais on va pas se demander laquelle est
la plus lisible, puisqu'elles sont équivalentes")

Comment vider la poubelle de « v » ? La construction idiomatique est

(1) prends une poubelle vide -- vector<T>()
(2) échange-la avec celle de v -- .swap(v)

Le tout donne « vector<T>().swap(v) »


C'est ton point de vue... Moi je trouve ca plus lisible de procéder comme ca
:

(1) prends v
(2) vide le dans une poubelle vide

Justement parcequ'on parle plus souvent de v que de la poubelle vide (dont
on se fiche pas mal)
Et ca ca donne v.swap(vector<T>())

--
Vincent

Avatar
Gabriel Dos Reis
"Vincent Lascaux" writes:

| > | Mais je trouve tout de même que lorsque l'on a un objet A a
| > | modifier, et un objet B créé pour le modifier, plus clair d'écrire
| > |
| > | A.swap( B ) ;
| > |
| > | que
| > |
| > | B.swap( A ) ;
| >
| > Mais, ils se modifient l'un et l'autre ! :-)
|
| Et c'est bien pour ca (comme on est tous d'accord que les deux écritures
| sont équivalentes) qu'on se demande laquelle des deux est la plus lisible

Non, ce n'est pas le propos initial. Il était

au lieu de :

v.swap( vector<T>() ) ;

qui semble plus naturel,
^^^^^^^

Ne déforme pas les propos en cours de discussion, cela pourrait se voir.

-- Gaby
Avatar
Vincent Lascaux
| Et c'est bien pour ca (comme on est tous d'accord que les deux écritures
| sont équivalentes) qu'on se demande laquelle des deux est la plus
lisible


Non, ce n'est pas le propos initial. Il était

au lieu de :

v.swap( vector<T>() ) ;

qui semble plus naturel,
^^^^^^^

Ne déforme pas les propos en cours de discussion, cela pourrait se voir.


OK, restons avec "plus naturel"...

--
Vincent

Avatar
drkm
Gabriel Dos Reis writes:

drkm writes:

| Mais je trouve tout de même que lorsque l'on a un objet A a
| modifier, et un objet B créé pour le modifier, plus clair d'écrire
|
| A.swap( B ) ;
|
| que
|
| B.swap( A ) ;


[...]

Comment vider la poubelle de « v » ? La construction idiomatique est

(1) prends une poubelle vide -- vector<T>()
(2) échange-la avec celle de v -- .swap(v)

Le tout donne « vector<T>().swap(v) »


Je signale en passant que cet exemple, l'exemple initial de la
sous-discussion, apporte une contrainte supplémentaire à la
sous-sous-discussion (citée ci-dessus), puisque dans ce cas une seule
des deux écritures est légale :-).

Tu m'as convaincu. En reprenant l'exemple ci-dessus, je tenais le
raisonnement :

1/ crée l'objet B, dont le but est de modifier A ;

2/ prend A, et envoie-lui le message de modification avec B en
paramètre.

Ton raisonnement est donc, si je ne m'abuse :

1/ crée l'objet B, dont le but est de modifier A ;

2/ envoie-lui le message de modification avec A en paramètre.

Les deux se valent. Évidemment, puisque std::swap() ne différencie
pas ces arguments. Je voulais voir une manière de voir les choses,
alors que cela est artificiel.

| Je m'attend plus à ce qu'un objet soit modifié par le message qu'on
| lui envoit que le paramètre soit modifié par le message dont il est le
| paramètre.

t'as pas encore été corrompu par les apôtres OO des getters ? ;-)


Référence à une discussion récente ?

--drkm

Avatar
Gabriel Dos Reis
drkm writes:


[...]

| 1/ crée l'objet B, dont le but est de modifier A ;
|
| 2/ prend A, et envoie-lui le message de modification avec B en
| paramètre.
|
| Ton raisonnement est donc, si je ne m'abuse :
|
| 1/ crée l'objet B, dont le but est de modifier A ;
|
| 2/ envoie-lui le message de modification avec A en paramètre.

Oui.

-- Gaby
Avatar
Loïc Joly
drkm wrote:
Mais je trouve tout de même que lorsque l'on a un objet A a
modifier, et un objet B créé pour le modifier, plus clair d'écrire

A.swap( B ) ;

que

B.swap( A ) ;



<Disclaimer>
Je n'ai que survolé la discussion, désolé si je reviens sur un point
déjà mentionné)
</Disclaimer>

Et que penses-tu de l'écriture :
std::swap(v, vector<T>());

Elle me semble avoir l'avantage de ne favoriser aucun des termes, ce qui
n'est pas mal pour une fonction cummutative.

--
Loïc

Avatar
Franck Branjonneau
Loïc Joly écrivait:

drkm wrote:
Mais je trouve tout de même que lorsque l'on a un objet A a
modifier, et un objet B créé pour le modifier, plus clair d'écrire
A.swap( B ) ;
que
B.swap( A ) ;


Et que penses-tu de l'écriture :
std::swap(v, vector<T>());


C'est certainement la plus expressive -- après v.clear(); mais
v.clear() ne libère pas la mémoire et std::swap(v, vector<T>()) est
illégal (st::swap prends des références non constantes).
--
Franck Branjonneau


Avatar
Gabriel Dos Reis
Loïc Joly writes:

| Et que penses-tu de l'écriture :
| std::swap(v, vector<T>());

Elle ne marche pas.

-- Gaby
1 2 3 4