当向量增长时如何强制移动语义? [英] How to enforce move semantics when a vector grows?

查看:37
本文介绍了当向量增长时如何强制移动语义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

这篇关于当向量增长时如何强制移动语义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆