How to enforce move semantics when a vector grows?(当向量增长时如何强制移动语义?)
问题描述
我有一个 std::vector 某个类 A 的对象.这个类很重要,并且定义了复制构造函数和移动构造函数.
I have a std::vector of objects of a certain class A. The class is non-trivial and has copy constructors and move constructors defined.
std::vector<A> myvec;
如果我用 A 对象填充向量(例如使用 myvec.push_back(a)),向量将增大,使用复制构造函数 A( const A&) 来实例化向量中元素的新副本.
If I fill-up the vector with A objects (using e.g. myvec.push_back(a)), the vector will grow in size, using the copy constructor A( const A&) to instantiate new copies of the elements in the vector.
我可以以某种方式强制使用 A 类的移动构造函数吗?
Can I somehow enforce that the move constructor of class A is beging used instead?
推荐答案
您需要使用 通知 C++(特别是 .然后当向量增长时会调用移动构造函数.std::vector)您的移动构造函数和析构函数不会抛出异常noexcept
You need to inform C++ (specifically std::vector) that your move constructor and destructor does not throw, using noexcept. Then the move constructor will be called when the vector grows.
这是如何声明和实现一个std::vector遵守的移动构造函数:
This is how to declare and implement a move constuctor that is respected by std::vector:
A(A && rhs) noexcept {
std::cout << "i am the move constr" <<std::endl;
... some code doing the move ...
m_value=std::move(rhs.m_value) ; // etc...
}
如果构造函数不是noexcept,std::vector就不能使用它,因为它不能保证标准要求的异常保证.
If the constructor is not noexcept, std::vector can't use it, since then it can't ensure the exception guarantees demanded by the standard.
有关标准中所说的更多信息,请阅读C++ 移动语义和异常
For more about what's said in the standard, read C++ Move semantics and Exceptions
感谢 Bo,他暗示这可能与例外有关.还要考虑 Kerrek SB 的建议并尽可能使用 emplace_back.它可以更快(但通常不是),它可以更清晰、更紧凑,但也存在一些缺陷(尤其是非显式构造函数).
Credit to Bo who hinted that it may have to do with exceptions. Also consider Kerrek SB's advice and use emplace_back when possible. It can be faster (but often is not), it can be clearer and more compact, but there are also some pitfalls (especially with non-explicit constructors).
编辑,通常默认是你想要的:移动所有可以移动的,复制其余的.要明确要求,请写
Edit, often the default is what you want: move everything that can be moved, copy the rest. To explicitly ask for that, write
A(A && rhs) = default;
这样做,您将在可能的情况下获得 noexcept:是默认值移动定义为 noexcept 的构造函数?
Doing that, you will get noexcept when possible: Is the default Move constructor defined as noexcept?
请注意,早期版本的 Visual Studio 2015 及更早版本不支持这一点,即使它支持移动语义.
Note that early versions of Visual Studio 2015 and older did not support that, even though it supports move semantics.
这篇关于当向量增长时如何强制移动语义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:当向量增长时如何强制移动语义?
基础教程推荐
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
- 初始化列表*参数*评估顺序 2021-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- CString 到 char* 2021-01-01
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
