我有一个 std::vector
对象的某个类 A
。该类非常重要,并且定义了复制构造函数 和 move 构造函数。
std::vector<A> myvec;
如果我用 A
对象填充 vector (使用例如 myvec.push_back(a)
), vector 的大小会增加,使用复制构造函数 A( const A&)
实例化 vector 中元素的新拷贝。
我能否以某种方式强制开始使用类 A
的 move 构造函数?
最佳答案
您需要使用 noexcept
通知 C++(特别是 std::vector
)您的 move 构造函数和析构函数不会抛出异常。然后 move 构造函数将在 vector 增长时被调用。
这是声明和实现 std::vector
所遵循的 move 构造函数的方法:
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
不能使用它,因为它不能确保标准要求的异常保证。
有关标准内容的更多信息,请阅读 C++ Move semantics and Exceptions
感谢 Bo,他暗示这可能与异常有关。还要考虑 Kerrek SB 的建议并尽可能使用 emplace_back
。它可以更快(但通常不会),可以更清晰、更紧凑,但也有一些缺陷(尤其是对于非显式构造函数)。
编辑,通常默认就是你想要的: move 所有可以 move 的,复制其余的。要明确要求,请写
A(A && rhs) = default;
这样做,您将在可能的情况下获得 noexcept:Is the default Move constructor defined as noexcept?
请注意,Visual Studio 2015 及更早版本的早期版本不支持该功能,尽管它支持 move 语义。
关于c++ - vector 增长时如何强制执行 move 语义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42317826/