Dec 28, 2021

[C++] some move semantics wrap-up (interesting there's a thing i didn't realize :-) )

Reference:
The Hidden Secrets of Move Semantics - Nicolai Josuttis - CppCon 2020

https://www.youtube.com/watch?v=TFMKjL38xAI


  • const variable disables move semantics; i.e. std::move(const type); is having type of:
    const Type&& t;
    
    void take(Type&&);
    
    take(t) // invalid
  • Don't return const value from a function. This will hinder the receiver function which has the signature of:
    void take(Type &&);
    const Type getValue();
    void take(Type &&);
    
    take(getValue()); // invalid
    
  • const&& is possible, but a semantic contradiction; i.e no move constructor will take const&& type.
  • To always adopt values you can take by value and move
    If move is cheap (e.g., to init string members)
  • T&& and auto&& are universal/forwarding references
    Unless
     T is not a local function template parameter
    Unless the argument is const
    Unless T is a type expression (e.g., T::value_type)
  • std::string&& can be a universal reference in full specializations; i.e.
    template<typename T>
    void Fun(T&&);
    
    template<>
    void Fun(std::string&&); // universal reference with type std::string; NOT r-value reference.
    
  • Universal reference does not always forward
  • Getters should return by value
    or should be overloaded on reference qualifiers.
    Do NOT loop over getter return temporary object.
  • Use auto&& in a generic range-based for loop; this is due if looping over std::vector<bool> an temporary proxy object is created and auto& CANNOT bind to it.
  • The range-based for loop is broken
    when iterating over references to temporaries
  • Use std::move() for member functions that is decorated as &&(i.e. only works on r-value object)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.