Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Where to type_std_move?

1,127 views

Published on

Short presentation based on my article http://oliora.github.io/2016/02/12/where-to-put-std-move.html

Published in: Software
  • Be the first to comment

Where to type_std_move?

  1. 1. Where to type std::move? Andrey Upadyshev Licensed under a CC BY-SA 4.0 License. Version 2016-04-26-1
  2. 2. The Problem void foo(Object && object) { // Should we apply std::move // to the object member? consume( std::move(object.member) ); // or to the object itself? consume( std::move(object).member ); } Note that it’s all related to std::forward as well.
  3. 3. What the heck, is there a difference? It is. Sometimes. std::move(object.member) • Means: cast a result of the object member access to a [cv-qualified] rvalue. • The result is always an rvalue. std::move(object).member • Means: cast the object to a [cv-qualified] rvalue then access its member. • If member is neither a static member nor a reference the result is an rvalue. • Otherwise the result is lvalue.
  4. 4. Why should I care? std::move(object.member) can accidentally move from a shared object if applied to a reference or a static member: class Object { Member& member; … }; ... std::move(object.member) std::move(object).member never does so. Think about generic code or changing a member type as a result of refactoring.
  5. 5. Generic code example Somewhere in the heart of the generic code: consume(std::move(std::get<i>(tuple))...); No idea, what’s in the tuple. It can be a value or a reference. When accidental move from a shared object is happened it will be a disaster. This approach is safe (or at least safer): consume(std::get<i>(std::move(tuple))...);
  6. 6. Sometimes it may be really different Slice from a tuple. Member that are rvalues are moved: auto tuple = hana::make_tuple("abc"s, "def"s, "ghi"s, "jkl"s); consume(hana::slice_c<0, 2>(std::move(tuple))); consume(hana::slice_c<2, 4>(std::move(tuple))); Applying std::move at the last step is useless, members are already copied inside slice: consume(std::move(hana::slice_c<0, 2>(tuple))); // copy Another example where behavior may differ is ref-qualified methods.
  7. 7. Where to type what? • std::move(object.member) to unconditionally move from a member. • std::move(object).member to tell that the object is actually an rvalue then only the safe things can happen J
  8. 8. Links 1. Andrey Upadyshev, What's the difference between std::move(object.member) and std::move(object).member? http://oliora.github.io/2016/02/12/where-to-put-std-move.html 2. Louis Dionne, A tentative notion of move-independence http://ldionne.com/2016/02/17/a-tentative-notion-of-move-independence/ 3. Reddit thread https://www.reddit.com/r/cpp/comments/45w3fs/whats_the_difference_between_stdmoveo bjectmember/ 4. The C++ Standard: Class Member Access [expr.ref-4] http://eel.is/c++draft/expr.ref#4

×