Сообщение Почему вектор копирует данные при расширении? от 23.10.2018 14:18
Изменено 23.10.2018 14:23 toro
Почему вектор копирует данные при расширении?
День добрый. Напомните, пожалуйста, в чем причина такого поведения?
Если же в классе закрыть копирование, то все начинает муваться:
Соответственно, почему, когда вектор расширяется, он в новосозданный буфер из старого копирует данные, а не мувает?
Если б вызывалось std::move из старого в новый, то вызывались бы конструкторы перемещения, что легко проверить:
class Test
{
std::string a;
public:
Test (const char * pa)
{
a = pa;
std::cout << "ctor\n";
}
Test (const Test & t)
{
a = t.a;
std::cout << "copy ctor: " << a << "\n";
}
Test (Test && t)
{
a = std::move (t.a);
std::cout << "move ctor: " << a << "\n";
}
Test & operator = (const Test & t)
{
a = t.a;
std::cout << "copy =: " << a << "\n";
return *this;
}
Test & operator = (Test && t)
{
a = std::move (t.a);
std::cout << "move =: " << a << "\n";
return *this;
}
};
int main ()
{
std::vector <Test> v;
Test t1("1"), t2("a"), t3("10");
v.emplace_back (std::move (t1));
v.emplace_back (std::move (t2));
v.emplace_back (std::move (t3));
return 0;
}
output:
ctor
ctor
ctor
move ctor: 1
move ctor: a
copy ctor: 1
move ctor: 10
copy ctor: 1
copy ctor: a
Если же в классе закрыть копирование, то все начинает муваться:
class Test
{
std::string a;
public:
Test (const char * pa)
{
a = pa;
std::cout << "ctor\n";
}
Test (const Test & t) = delete;
Test & operator = (const Test & t) = delete;
Test (Test && t)
{
a = std::move (t.a);
std::cout << "move ctor: " << a << "\n";
}
Test & operator = (Test && t)
{
a = std::move (t.a);
std::cout << "move =: " << a << "\n";
return *this;
}
};
int main
{
// такой же
}
output:
ctor
ctor
ctor
move ctor: 1
move ctor: a
move ctor: 1
move ctor: 10
move ctor: 1
move ctor: a
Соответственно, почему, когда вектор расширяется, он в новосозданный буфер из старого копирует данные, а не мувает?
Если б вызывалось std::move из старого в новый, то вызывались бы конструкторы перемещения, что легко проверить:
class Test
{
// такой же, как в первом примере, с доступными к-рами копирования
};
std::vector <Test> v, v2;
Test t1("1"), t2("a"), t3("10");
v.emplace_back (std::move (t1));
v.emplace_back (std::move (t2));
v.emplace_back (std::move (t3));
v2.reserve (3);
v2.emplace (v2.begin (), std::move (v[0]));
output:
ctor
ctor
ctor
move ctor: 1
move ctor: a
copy ctor: 1
move ctor: 10
copy ctor: 1
copy ctor: a
move ctor: 1
Почему вектор копирует данные при расширении?
День добрый. Напомните, пожалуйста, в чем причина такого поведения?
Если же в классе закрыть копирование, то все начинает муваться:
Соответственно, почему, когда вектор расширяется, он в новосозданный буфер из старого копирует данные, а не мувает?
Если б вызывалось std::move из старого в новый, то вызывались бы конструкторы перемещения, что легко проверить:
class Test
{
std::string a;
public:
Test (const char * pa)
{
a = pa;
std::cout << "ctor\n";
}
Test (const Test & t)
{
a = t.a;
std::cout << "copy ctor: " << a << "\n";
}
Test (Test && t)
{
a = std::move (t.a);
std::cout << "move ctor: " << a << "\n";
}
Test & operator = (const Test & t)
{
a = t.a;
std::cout << "copy =: " << a << "\n";
return *this;
}
Test & operator = (Test && t)
{
a = std::move (t.a);
std::cout << "move =: " << a << "\n";
return *this;
}
};
int main ()
{
std::vector <Test> v;
Test t1("1"), t2("a"), t3("10");
v.emplace_back (std::move (t1));
v.emplace_back (std::move (t2));
v.emplace_back (std::move (t3));
return 0;
}
output:
ctor
ctor
ctor
move ctor: 1
move ctor: a
copy ctor: 1
move ctor: 10
copy ctor: 1
copy ctor: a
Если же в классе закрыть копирование, то все начинает муваться:
class Test
{
std::string a;
public:
Test (const char * pa)
{
a = pa;
std::cout << "ctor\n";
}
Test (const Test & t) = delete;
Test & operator = (const Test & t) = delete;
Test (Test && t)
{
a = std::move (t.a);
std::cout << "move ctor: " << a << "\n";
}
Test & operator = (Test && t)
{
a = std::move (t.a);
std::cout << "move =: " << a << "\n";
return *this;
}
};
int main
{
// такой же
}
output:
ctor
ctor
ctor
move ctor: 1
move ctor: a
move ctor: 1
move ctor: 10
move ctor: 1
move ctor: a
Соответственно, почему, когда вектор расширяется, он в новосозданный буфер из старого копирует данные, а не мувает?
Если б вызывалось std::move из старого в новый, то вызывались бы конструкторы перемещения, что легко проверить:
class Test
{
// такой же, как в первом примере, с доступными к-рами копирования
};
int main ()
{
std::vector <Test> v;
Test t1 ("1"), t2 ("a"), t3 ("10");
v.emplace_back (std::move (t1));
v.emplace_back (std::move (t2));
v.emplace_back (std::move (t3));
std::vector <Test> v2;
v2.reserve (3);
v2.emplace (v2.begin (), std::move (v[0]));
return 0;
}
output:
ctor
ctor
ctor
move ctor: 1
move ctor: a
copy ctor: 1
move ctor: 10
copy ctor: 1
copy ctor: a
move ctor: 1 <---