J'ai accès depuis quelques jours à une config Linux, et j'en profite pour tester le mode experimental c++0x de gcc. J'essaie de comprendre les rvalue references et l'impact qu'elles auront sur notre manière de coder, mais je bute sur deux problèmes :
Question 1
Première essai. Une classe "movable" mais pas copiable
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | struct NonCopyable { NonCopyable() = default; NonCopyable(NonCopyable&&) = default; //empeche la copie NonCopyable(const NonCopyable&) = delete; NonCopyable& operator=(const NonCopyable&) = delete; }; |
Ne pourrait pas avoir un move constructeur qui ferait des move membre à membre ?
Code : | Sélectionner tout |
1 2 3 4 5 | NonCopyable(NonCopyable&& ncp): membre1(move(ncp.membre1), membre2(move(ncp.membre2), ... |
A l'heure actuelle, pour appliquer un traitement sur un objet lourd, la syntaxe revient toujours plus ou moins à foo(HeavyClass&, Param1, Param2, Param3...). Esthétiquement je préfère de beaucoup la syntaxe HeavyClass foo(Param1, Param2, Param3)... mais il y a la copie.
J'avais cru comprendre que les rvalue references allaient réunir les deux mondes et nous permettre ce genre de chose :
X&& foo();
X x = foo();
Sans copie aucune. \0/
Ben il semble que non.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | std::vector<std::string>&& parse(const std::string& s, char token) { std::vector<std::string> result; std::string::size_type first = 0, last; while (first != std::string::npos) { last = s.find_first_of(token, first); result.push_back(s.substr(first, last - first)); first = s.find_first_not_of(token, last); } return move(result); // move explicite } std::vector<std::string> parse = foo("Le.c++0x.c'est.l'avenir.",'.'); |
Le mode debug confirme que le destructeur de result est appelé en sortant du scope de parse(), avant le move constructeur, d'où la segmentation fault. Or je croyais que le rôle même de std::move était de prolonger un peu les temporaires pour leur donner le temps de faire les opérations impliquant les rvalue reference et seulement ensuite d'être détruit. Ou cela coince-t-il ?
Merci!