Exemples pour un tutoriel

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à tous,

Je suis actuellement en train de rédiger un cours sur la sémantique de mouvement, qui est en beta. J'aimerai donc bénéficier de vos retours, et surtout avoir des exemples permettant d'illustrer l'utilité de la move semantic, que j'ajouterai dans la section Exemples.

Merci d'avance !

Plus on apprend, et, euh… Plus on apprend. | Coliru, parfait pour tester ses codes sources !

+0 -0

Cette réponse a aidé l'auteur du sujet

Je vais être hyper réducteur: je n'en ai plus besoin, je move :).

Par contre, la sémantique de mouvement à changé ma façon d'envoyer des paramètres, il y a beaucoup plus de copie qu'avant (cf. type plein). Mais en apparence seulement, l'appelant décide lui-même si oui ou non une rvalue est approprié. Bien sûr, je ne le fais pas pour tout, mais uniquement pour les paramètres qui vont être absorbés par la classe/fonction (principalement les constructeurs).

Parmi les exemples possibles, j'en vois 2:

  • responsabilité unique (unique_ptr est un bon exemple)
  • performance (parce qu'un move n'est pas moins rapide qu'une copie quand possible). Je dis performance, mais il serait mieux de parler de sémantique: s'il y a copie, c'est que la variable d'origine est importante. Comme exemple, une implémentation de std::vector ::erase(It) ? while (cin >> s) vec.emplace_back(std::move(s)) ?

Il y a quand même un piège: les structures ne garantissent pas toujours l'affectation de mouvement sur soi-même. C'est le cas de std::vecteur, il faut passer par une temporaire pour avoir cet garanti.

Le cours va-t-il parler des fonctions ref-qualifiée ? Le truc qui permet de faire

  • a.foo() // affiche "je suis "
  • std::move(a).foo() // affiche "schizo !"

PS: Comment fait-on pour voir les tutos en bétâ ?

Édité par jo_link_noir

+0 -0
Auteur du sujet

Salut et merci pour ta reponse !

Pour voir les tutoriels en beta, tu peux aller sur forum -> tag beta -> mon sujet -> lien vers le tutoriel. Desole, je ne peux pas mettre un lien direct maintenant, je l ajouterai demain.

Sinon, il peut etre interessant de mentionner les fonctions ref qualifiees dans la section exemple je n'y avais pas pense.

En revanche, je ne comprends pas pourquoi la move semantic te fait passer tes params par copie ? Pour continuer a utiliser l objet "source" ?

Plus on apprend, et, euh… Plus on apprend. | Coliru, parfait pour tester ses codes sources !

+0 -0

Cette réponse a aidé l'auteur du sujet

J'ai noté une erreur concernant les constructeurs/operateur= ajoutés par le compilo.

Le compilateur crée toujours les 5 fonctions (ctor par défaut, T const& et T&&). Par contre, si les prototypes prenant const& sont définit, les prototypes avec T && ne sont plus accessible.

L'implémentation de operator=(T&&) est plutôt moyenne pour plusieurs raisons:

  • La condition (je n'ai jamais aimé cette vérification)
  • le swap sur m_ptr qui va prolonger la durée de vie du pointeur.
  • (return mal placé)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
X& X::operator=(X&& autre) noexcept
{
  X(std::move(autre)).swap(*this);
  // plus jolie que
  //X tmp(std::move(autre));
  //delete m_ptr;
  //m_ptr = std::move(tmp.m_ptr);
  //m_phrase = std::move(tmp.m_phrase);
  return *this;
}

X::X(X&& autre) noexcept
: m_ptr(std::exchange(autre.m_ptr, nullptr))
, m_phrase(std::move(autre.m_phrase))
{}

void X::swap(X & autre) noexcept
{
  std::swap;
  swap(m_ptr, autre.m_ptr);
  swap(m_phrase, autre.m_phrase);
}

En revanche, je ne comprends pas pourquoi la move semantic te fait passer tes params par copie ? Pour continuer a utiliser l objet "source" ?

Pour profiter de la copie élision. La flemme d'expliquer (l'explication commence au titre "Mais ça c'était avant…").

Tu peux aussi mentionner std::forward et std::move_if_noexcept (les containers de la sl ont une garantie très forte au niveau des exceptions: pas de mouvement si move-ctor pas noexcept (autrement, la séquence ne pourrait pas être dans un état cohérent si une exception est lancée)).

Édité par jo_link_noir

+1 -0
Auteur du sujet

Merci pour les informations, je ne savais pas que l'on appliquait l'idiome copy-and-swap (ou plutôt move-and-swap) pour l'opérateur d'affectation par mouvement. Je changerai ça. Je corrigerai aussi les fonctions crées par défaut par le compilateur. Enfin, il me semble une bonne idée de mentionner std::move_if_no_except, mais je ne suis pas sûr de mentionner std::forward, étant donné que le cours se veut être une introduction à la sémantique de mouvement, pas à l'utilisation des rvalue-references. Cependant, je réfléchis encore : j'ajouterai peut-être une section "Autres exemples d'utilisation des rvalue-references", où je mettrai par exemple les fonctions ref-qualifiées et std::forward.

Édité par mehdidou99

Plus on apprend, et, euh… Plus on apprend. | Coliru, parfait pour tester ses codes sources !

+0 -0
Auteur du sujet

Sinon, l'article de T. Becker est-il une bonne référence pour ceux qui veulent approfondir ? Des propositions de liens supplémentaires à ajouter en fin de cours seraient aussi les bienvenues :)

Plus on apprend, et, euh… Plus on apprend. | Coliru, parfait pour tester ses codes sources !

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte