Я пытаюсь вызвать конструктор перемещения в приведенном ниже коде, где происходит добавление двух списков. Учитывая то, что я прочитал в книге Страуструпа, конструктор перемещения должен вызываться при возврате operator+(const X& a, const X& b)
, однако это не соответствует выводам ниже. Вызывается только назначение перемещения.
Кто-нибудь знает, почему конструктор перемещения не вызывается при возврате из функции?
Спасибо
#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