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 here
void 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 valid
void 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 copy
T 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 pessimization
void 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) {
}