copy-and-swap

What is the Rule of Four (and a half)?

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-29 02:31:32
问题 For properly handling object copying, the rule of thumb is the Rule of Three. With C++11, move semantics are a thing, so instead it's the Rule of Five. However, in discussions around here and on the internet, I've also seen references to the Rule of Four (and a half), which is a combination of the Rule of Five and the copy-and-swap idiom. So what exactly is the Rule of Four (and a half)? Which functions need to be implemented, and what should each function's body look like? Which function is

public friend swap member function

只谈情不闲聊 提交于 2019-11-28 14:55:50
In the beautiful answer to the copy-and-swap-idiom there is a piece of code I need a bit of help: class dumb_array { public: // ... friend void swap(dumb_array& first, dumb_array& second) // nothrow { using std::swap; swap(first.mSize, second.mSize); swap(first.mArray, second.mArray); } // ... }; and he adds a note There are other claims that we should specialize std::swap for our type, provide an in-class swap along-side a free-function swap, etc. But this is all unnecessary: any proper use of swap will be through an unqualified call, and our function will be found through ADL. One function

public friend swap member function

馋奶兔 提交于 2019-11-27 19:40:44
问题 In the beautiful answer to the copy-and-swap-idiom there is a piece of code I need a bit of help: class dumb_array { public: // ... friend void swap(dumb_array& first, dumb_array& second) // nothrow { using std::swap; swap(first.mSize, second.mSize); swap(first.mArray, second.mArray); } // ... }; and he adds a note There are other claims that we should specialize std::swap for our type, provide an in-class swap along-side a free-function swap, etc. But this is all unnecessary: any proper use

Should the Copy-and-Swap Idiom become the Copy-and-Move Idiom in C++11?

不打扰是莪最后的温柔 提交于 2019-11-27 13:10:30
As explained in this answer , the copy-and-swap idiom is implemented as follows: class MyClass { private: BigClass data; UnmovableClass *dataPtr; public: MyClass() : data(), dataPtr(new UnmovableClass) { } MyClass(const MyClass& other) : data(other.data), dataPtr(new UnmovableClass(*other.dataPtr)) { } MyClass(MyClass&& other) : data(std::move(other.data)), dataPtr(other.dataPtr) { other.dataPtr= nullptr; } ~MyClass() { delete dataPtr; } friend void swap(MyClass& first, MyClass& second) { using std::swap; swap(first.data, other.data); swap(first.dataPtr, other.dataPtr); } MyClass& operator=

Why do some people use swap for move assignments?

旧巷老猫 提交于 2019-11-26 23:43:16
For example, stdlibc++ has the following: unique_lock& operator=(unique_lock&& __u) { if(_M_owns) unlock(); unique_lock(std::move(__u)).swap(*this); __u._M_device = 0; __u._M_owns = false; return *this; } Why not just assign the two __u members to *this directly? Doesn't the swap imply that __u is assigned the *this members, only to later have then assigned 0 and false... in which case the swap is doing unnecessary work. What am I missing? (the unique_lock::swap just does an std::swap on each member) It's my fault. (half-kidding, half-not). When I first showed example implementations of move

Should the Copy-and-Swap Idiom become the Copy-and-Move Idiom in C++11?

情到浓时终转凉″ 提交于 2019-11-26 22:22:45
问题 As explained in this answer, the copy-and-swap idiom is implemented as follows: class MyClass { private: BigClass data; UnmovableClass *dataPtr; public: MyClass() : data(), dataPtr(new UnmovableClass) { } MyClass(const MyClass& other) : data(other.data), dataPtr(new UnmovableClass(*other.dataPtr)) { } MyClass(MyClass&& other) : data(std::move(other.data)), dataPtr(other.dataPtr) { other.dataPtr= nullptr; } ~MyClass() { delete dataPtr; } friend void swap(MyClass& first, MyClass& second) {

What is copy elision and how does it optimize the copy-and-swap idiom?

馋奶兔 提交于 2019-11-26 20:08:28
I was reading Copy and Swap . I tried reading some links on Copy Elision but could not figure out properly what it meant. Can somebody please explain what this optimization is, and especially what is mean by the following text This is not just a matter of convenience but in fact an optimization. If the parameter (s) binds to a lvalue (another non-const object), a copy of the object is made automatically while creating the parameter (s). However, when s binds to a rvalue (temporary object, literal), the copy is typically elided, which saves a call to a copy constructor and a destructor. In the

Why do some people use swap for move assignments?

只愿长相守 提交于 2019-11-26 08:48:54
问题 For example, stdlibc++ has the following: unique_lock& operator=(unique_lock&& __u) { if(_M_owns) unlock(); unique_lock(std::move(__u)).swap(*this); __u._M_device = 0; __u._M_owns = false; return *this; } Why not just assign the two __u members to *this directly? Doesn\'t the swap imply that __u is assigned the *this members, only to later have then assigned 0 and false... in which case the swap is doing unnecessary work. What am I missing? (the unique_lock::swap just does an std::swap on

What is copy elision and how does it optimize the copy-and-swap idiom?

情到浓时终转凉″ 提交于 2019-11-26 07:31:37
问题 I was reading Copy and Swap. I tried reading some links on Copy Elision but could not figure out properly what it meant. Can somebody please explain what this optimization is, and especially what is mean by the following text This is not just a matter of convenience but in fact an optimization. If the parameter (s) binds to a lvalue (another non-const object), a copy of the object is made automatically while creating the parameter (s). However, when s binds to a rvalue (temporary object,

When is overloading pass by reference (l-value and r-value) preferred to pass-by-value?

自古美人都是妖i 提交于 2019-11-26 05:27:20
问题 I have seen it said that a operator= written to take a parameter of the same type by-value serves as both copy assignment operator and move assignment operator in C++11: Foo& operator=(Foo f) { swap(f); return *this; } Where the alternative would be more than twice as many lines with a lot of code repetition, and potential for error: Foo& operator=(const Foo& f) { Foo f2(f); swap(f2); return *this; } Foo& operator=(Foo&& f) { Foo f2(std::move(f)); swap(f2); return *this; } In what