void f(const T&);Objects for reading: ~const~ reference
// example
void Align(const std::vector<int>& page_ids) {
}
Align(page_ids);void f(T);Primitives and impossible to copy types: value
// example
void SetOrigin(int count, Point origin,
std::unique_ptr<Shape> box) {
}
SetOrigin(n, org, std::move(box));void f(T&&);Objects for ownership: rvalue reference
// example
void SetTitle(std::string&& title) {
m_title = std::move(title); // steal title’s data
}
SetTitle(std::move(app_title)); // app_title empty herevoid f(T&&);
void f(const T&);Provide two overloads; for callers wanting to
- relinquish ownership: rvalue reference
- retain ownership: ~const~ reference
// example
void SetTitle(std::string&& title) { // for relinquishers
m_title = std::move(title); // cheap move
}
void SetTitle(const std::string& title) { // for retainers
m_title = title; // expensive deep copy
}
SetTitle(std::move(page_title)); // page_title empty
SetTitle(doc_title); // doc_title validvoid f(T);Objects for ownership during construction: value
// example
Image::Image(Pixels p) : m_pixels(std::move(p)) {
}
auto i1 = Image(std::move(p1)); // relinquish; cheap move
auto i2 = Image(p2); // retain; expensive deep copyT f();Return by value; prvalues get moved, copy evaded for move-unfriendly types by RVO
// example
Image Render() {
return Image(/*some params*/);
}
Image i = Render(); // using std::move(Render()) is pessimizationvoid f(T&);Take lvalue reference and fill data
Returning value (both move and copy) will lead to deep copy for PODs
// example
void Deduce(Properties& p) { /* read-write p */ }
// a move-unfriendly type (has no freestore data members)
struct Properties {
Point origin;
float size_x, size_y;
std::array<Margin, 4> margin_sizes;
}; T& f();
const T& f();Return lvalue reference to object outliving function and caller
// example
struct Application {
Document& GetDocument { return m_pdf; } // covariant return type
PDFDocument m_pdf;
}; // app outlives GetDocument() and temp() calls
void PrintDoc(Application& app) { app.GetDocument().Print(); }
int main() { Application app{str_pdf_path}; PrintDoc(app); }void f(T&);Objects for reading and writing: lvalue reference
// example
void AdjustMargins(std::vector<Margin>& margins) {
}