Usages of std::move
Usages of std::move
下面的问题是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;
}
一些假设:
我相信"移动- 1"和"移动2"之间没有显着区别
- 我相信"招3"和"招4"之间没有显着区别
- 据我所知,
std::forward
不是任何std::move
用法的良好替代品,因为没有模板
问题:所有std::move
用法是否有意义,或者其中任何一种都是不必要的?
你可以看到大多数std::move
都是删除它们所必需的,你的代码将无法编译。唯一的例外是Move 1
和Move 2
,代码仍然可以在没有它们的情况下编译,但只是因为调用了std::vector
复制构造函数。
如果要从对象移动,则几乎总是需要使用std::move
,唯一的例外是从临时移动和返回对象时。
相关文章:
- Usages of std::move
- 在C++中对T*类型执行std::move的意外行为
- 关于std::move的使用,是否有编译警告
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 通过实例理解std::move及其目的
- 返回一个带有 std::move 的对象并链接函数
- '[](std::list& list)<int>{return std::move(list)}(list)' 是否保证将 'list' 留空?
- 当 std::move 与 C 样式数组或不移动对象时会发生什么
- 为什么当我为 for(auto& it : myUnorderedMap) {... = std::move(it.second)} 时,我会得到一个 const 引用?
- std::move a const std::vector in a lambda capture
- "std::forward"和"std::move"真的不生成代码吗?
- std::vector move 而不是交换到空 vector 并释放存储
- 是否有必要使用 std::move?这不是已经是一个右值参考了吗?
- 如何在没有 std::move 的情况下移动临时对象
- 关于在成员重载中使用 std::move() 的问题
- 显式清除 std::move 之后的源资源
- std::move(key) 同时迭代unordered_map<字符串,字符串>?
- std::move(std::array) g++ vs visual-c++
- 使用 move std::string 的 .data() 成员不适用于小字符串?
- std::move(std::unique_ptr()) 组合是否有标准缩写