// http://stackoverflow.com/questions/19826045/trying-to-write-move-constructor-in-terms-of-move-assignment/19846215#19846215
// https://i...content-available-to-author-only...e.com/AnwDvD
#include<algorithm>
#include<cassert>
#include<cstring>
#include<iostream>
class String
{
char* m_data;
int m_len;
public:
const volatile String&& operator=(String&) volatile const = delete; // make it as undesirable as possible!
void swap(String& rhs) throw()
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
std::swap(m_data, rhs.m_data);
std::swap(m_len, rhs.m_len);
}
template<typename T>
String& operator=(T templated_copy_and_swap) {
std::cout << __PRETTY_FUNCTION__ << " (Templated ) Assignment by (optional) copy and (not-optional) swap" << std::endl;
templated_copy_and_swap.swap(*this);
return *this;
}
String(String&& move_constructor) throw() // The move constructor, we wish to use operator= here
: m_data(NULL)
, m_len(0)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
//move_constructor.swap(*this); // This was the original line we wish to replace
operator=(std::move(move_constructor)); // It works!
}
String& operator=(String && move_assignment) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
move_assignment.swap(*this);
return *this;
}
/* Below are just some other constructors that are required
* to build a working demonstration
*/
String(const String ©_constructor) {
std::cout << __PRETTY_FUNCTION__ << " Copy constructor" << std::endl;
m_len = copy_constructor.m_len;
m_data = new char[m_len+1];
strncpy(m_data, copy_constructor.m_data, m_len+1);
}
~String() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
if(m_data) {
std::cout << " ~\"" << m_data << "\"" << std::endl;
delete[] m_data;
} // otherwise, this String was moved-from. Nothing to delete
}
template<size_t lenPlusOne>
explicit String(const char (&x)[lenPlusOne]) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
m_data = new char[lenPlusOne];
strncpy(m_data, x, lenPlusOne);
m_len = lenPlusOne - 1; // to deal with the trailing '\0'
assert(m_data[m_len] == '\0');
}
};
String returnsT() {
std::cout << __PRETTY_FUNCTION__ << " Inside returnsT(). It will do some stuff here." << std::endl;
String s("returnsT");
std::cout << __PRETTY_FUNCTION__ << " Inside returnsT(). About to return." << std::endl;
return s;
}
int main() {
String s1("first");
String s2("second");
String s3("third");
std::cout << std::endl;
std::cout << " === Situation A): Assign from l-value. Copy required." << std::endl << std::endl;
s1 = s2;
{
std::cout << std::endl;
std::cout << " === Situation B): Assign from returnsT() returning T. C++03 can optimize this, no copy *OR* move required after the return." << std::endl << std::endl;
s1 = returnsT();
}
{
std::cout << std::endl;
std::cout << " === Situation C): Assign from move() returning T&&." << std::endl << std::endl;
s1 = std::move(s3) ;
//s1 = StringRVRef(std::move(s3));
}
std::cout << std::endl;
std::cout << " === Done. main() will finish now, destructing the three local strings." << std::endl << std::endl;
}