c++ - vector 增长时如何强制执行 move 语义?

标签 c++ vector c++11 resize move-semantics

我有一个 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...
}

如果构造函数不是noexceptstd::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/

相关文章:

c++ - Qt - 具有自定义参数的可重用绘图函数

opencv - 如何为vector <Point3f>数据类型分配值

C++ 子程序 vector<vector<short>> 指针

c++ - 通过指针访问 std::vector 元素与 end()

c++ - 这种模式如何运作?

c++ - 使用状态创建 C++11 std::function<>

c++ - Qt中没有匹配的函数调用报错是什么

c++ - 了解 C/C++ 中的指针

c++ - 无法从 "initializer list"转换

c++ - 在 C++11 中,我想摆脱 pimpl idiom 中的原始指针