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

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

问题描述

我有一个std ::对象的某个类的对象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 类的move构造函数,而不是使用beging?

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 which 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 follow Kerrek SB's advice and use emplace_back when possible.

编辑默认是你想要的:移动可以移动的一切,复制其余。要明确要求,请写入

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:

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天全站免登陆