I'm trying to invoke the move constructor in the code below, where the addition of two lists occurs. Given what I read in the Stroustrup book, the move constructor should be invoked when operator+(const X& a, const X& b)
returns, however it does not per the output below. Only the move assignment is being invoked.
Does anyone know why the move constructor is not being invoked on return from function?
Thanks
#include <iostream>
#include <list>
using std::list;
using std::cout;
using std::initializer_list;
class X {
list<int> *p;
size_t sz;
public:
X() : p{ new list<int>(0) } { }
X(size_t size) : p{ new list<int>(size) }, sz {size} { }
X(initializer_list<int> li) : p{ new list<int>(li) }, sz { li.size() } { }
X(const X&);
X& operator=(const X&);
// move
X(X&&);
X& operator=(X&&);
size_t size() const { return sz; }
int &operator[](int);
int &operator[](int) const;
class size_mismatch { };
};
X::X(const X& a)
{
p = new list<int>();
for (auto pp : *(a.p))
p->push_back(pp);
sz = a.sz;
}
X& X::operator=(const X& a)
{
delete p;
p = new list<int>();
for (auto pp : *(a.p))
p->push_back(pp);
sz = a.sz;
return *this;
}
X::X(X&& a) : p{ a.p }, sz{ a.sz }
{
cout << "here0\n";
a.p = nullptr;
a.sz = 0;
}
X& X::operator=(X&& a)
{
cout << "here1\n";
p = a.p;
sz = a.sz;
a.p = nullptr;
a.sz = 0;
return *this;
}
int& X::operator[](int x)
{
for (auto &i : *p) {
if (x == 0) return i;
--x;
}
throw std::out_of_range("List container");
}
int& X::operator[](int x) const
{
for (auto &i : *p) {
if (x == 0) return i;
--x;
}
throw std::out_of_range("List container");
}
X operator+(const X& a, const X& b)
{
if (a.size()!=b.size())
throw X::size_mismatch{};
X res(a.size());
for (int i = 0; i != a.size(); ++i)
res[i] = a[i] + b[i];
return res;
}
int main(int argc, char *argv[])
{
X px = {0, 1, 2};
for (int i=0; i < px.size(); i++)
cout << px[i];
cout << '\n';
X py(px);
for (int i=0; i < py.size(); i++)
py[i]++;
for (int i=0; i < py.size(); i++)
cout << py[i];
cout << '\n';
X pz;
pz = py;
for (int i=0; i < pz.size(); i++)
cout << pz[i];
cout << '\n';
X ph;
// This should call move constructor
ph = px + py + pz;
for (int i=0; i < ph.size(); i++)
cout << ph[i];
cout << '\n';
return 0;
}
$ g++ -std=c++11 test62.cc && ./a.out
012
123
123
here1
258