Ниже в вопросе - упрощенная версия кода для SO. Исходный код:
- Получает структуру, которую нельзя изменять или делать недействительной
- Создает другую структуру, в которой некоторые данные скопированы из исходной структуры
- Новый Созданная структура не может быть изменена, все ее члены:
const
- Вновь созданная структура не может иметь конструктор, который знает об исходной структуре
Упрощенный код для SO не у меня нет исходной структуры, я просто составил данные с помощью циклов. Однако важная деталь заключается в том, что конструктору новой структуры будет передано std::vector
. Они заполняются в циклах и перемещаются в новую структуру
Мне пришло в голову, что std::vector
не понадобится после создания новой структуры, поэтому std::move
будет подходящим. В приведенном ниже коде я обозначил использование как «Перемещение 1», «Перемещение 2», «Перемещение 3» и «Перемещение 4»:
#include <iostream>
#include <vector>
struct A {
const int m_a;
A() = delete;
A(const int a_a) : m_a(a_a) {}
void display() const { std::cout << " " << m_a << "\n"; }
};
struct B {
const std::vector<A> m_as;
const int m_b;
B() = delete;
B(
std::vector<A>&& a_as,
const int a_b
) :
m_as(std::move(a_as)), // Move 1
m_b(a_b)
{}
void display() const {
std::cout << " " << m_b << ":\n";
for (const A& a : m_as)
a.display();
}
};
struct C {
const std::vector<B> m_bs1;
const std::vector<B> m_bs2;
C() = delete;
C(
std::vector<B>&& a_bs1,
std::vector<B>&& a_bs2
) :
m_bs1(std::move(a_bs1)), // Move 2
m_bs2(std::move(a_bs2)) // Move 2
{}
void display() const {
std::cout << "0:\n";
for (const B& b : m_bs1)
b.display();
std::cout << "1:\n";
for (const B& b : m_bs2)
b.display();
}
};
int main() {
// Manually making up data, actual usage will take data from a different
// kind of structure and populate vectors
std::vector<B> bs1, bs2;
for (int i = 0; i < 3; ++i) {
std::vector<A> as;
for (int j = 0; j < 2; ++j)
as.emplace_back(j);
bs1.emplace_back(std::move(as), i); // Move 3
}
for (int i = 0; i < 3; ++i) {
std::vector<A> as;
for (int j = 0; j < 2; ++j)
as.emplace_back(j);
bs2.emplace_back(std::move(as), i); // Move 3
}
C c(std::move(bs1), std::move(bs2)); // Move 4
c.display();
return 0;
}
Некоторые предположения :
- Я считаю, что нет значительной разницы между «Move 1» и «Move 2»
- Я считаю, что нет значительной разницы между «Move 3» и «Move 4»
- Насколько мне известно,
std::forward
не является хорошей заменой для любого из вариантов использования std::move
, потому что нет шаблонов
Вопрос : Все ли std::move
использования значимы или какие-либо из них не нужны?