C ++ 11移动语义行为特定问题 [英] C++11 Move semantics behaviour specific questions

查看:87
本文介绍了C ++ 11移动语义行为特定问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读以下文章,该文章对移动语义有很好的了解:

I have read the below post which gives a very good insight into move semantics:

有人可以向我解释移动语义吗?

但是我仍然无法理解有关移动语义的以下内容-

but I am still fail to understand following things regarding move semantics -

  1. 在没有移动构造函数的情况下,复制省略和RVO是否仍适用于类?

  1. Does copy elision and RVO would still work for classes without move constructors?

即使我们的类没有移动构造函数,但STL容器也有一个.对于

Even if our classes doesn't have move constructors, but STL containers has one. For operation like

std::vector<MyClass> vt = CreateMyClassVector();

并执行排序等操作.为什么STL不能在内部使用移动语义来通过不需要复制构造函数的复制省略或RVO等内部操作来改善此类操作?

and to perform operations like sorting etc. Why can't STL internally leverage move semantics to improve such operations internally using operations like copy elision or RVO which doesn't require move constructors?

3. 在以下情况下,我们会从移动语义中受益吗?

3. Do we get benefited by move semantics in below case -

std::vector< int > vt1(1000000, 5); // Create and initialize 1 million entries with value 5

std::vector< int > vt2(std::move(vt1)); // move vt1 to vt2

由于整数是原始类型,因此移动整数元素将不会提供任何优势. 或在执行移动操作后,此处vt2仅指向堆中的vt1内存,而vt1设置为null.实际发生了什么?如果是后者,则即使第2点也成立,我们可能不需要为类使用move构造函数.

as integer is a primitive type, moving integer elements will not offer any advantage. or here after move operation vt2 simply points to vt1 memory in heap and vt1 is set to null. what is actually happening? If latter is the case then even point 2 holds that we may not need move constructor for our classes.

4. 当使用std :: move在左值上调用push_back()时,例如:

4. When a push_back() is called using std::move on lvalue for e.g :

    std::vector<MyClass> vt;

    for(int i=0; i<10; ++i)
    {
        vt.push_back(MyClass());
    }

    MyClass obj;

    vt.push_back(std::move(obj));

现在,向量具有连续的内存分配,并且obj在内存中的其他位置定义了如何移动语义将obj内存移动到向量vt连续的内存区域,在这种情况下不会移动内存与复制内存一样好,如何通过简单地移动指向堆不同区域中的内存的指针,移动是否可以证明向量的连续内存需求??

now as vector has contiguous memory allocation, and obj is defined somewhere else in memory how would move semantics move the obj memory to vector vt contiguous memory region, wouldn't moving memory in this case is as good as copying memory, how does move justifies vectors contiguous memory requirements by simply moving a pointer pointing to a memory in different region of a heap.?

感谢提前解释!

[最初发布为移动语义澄清,但由于上下文有所更改,因此将其发布为新问题应尽快删除旧的问题.]

[Originally posted as Move semantics clarification but now as the context is changed a bit posting it as new question shall delete the old one ASAP.]

推荐答案

在没有移动构造函数的情况下,复制省略和RVO是否仍适用于类?

Does copy elision and RVO would still work for classes without move constructors?

是的,RVO仍然起作用.实际上,编译器应该选择:

Yes, RVO still kicks in. Actually, the compiler is expected to pick:

  • RVO(如果可能)
  • 移动构造(如果可能)
  • 复制结构(不得已)

为什么STL无法在内部使用移动语义来使用不需要移动构造函数的复制省略或RVO之类的操作来内部改善此类操作?

Why can't STL internally leverage move semantics to improve such operations internally using operations like copy elision or RVO which doesn't require move constructors?

STL容器 是可移动的,而不管其中存储的类型如何.但是,对容器中的对象 的操作需要对象的配合,因此,例如 sort (例如)仅在对象可移动的情况下才可以移动对象.

The STL containers are movable, regardless of the types stored within. However, operations on the objects in the container require the object cooperation, and as such sort (for example) may only move objects if those objects are movable.

在以下情况下,由于整数是原始类型,我们是否可以从移动语义中受益?

Do we get benefited by move semantics in below case [...] as integer is a primitive type ?

是的,是的,因为容器 可以移动,而不管其内容如何.根据您的推论,st2将窃取st1的内存.尽管未指定移动后st1的状态,所以我不能保证其存储将被取消.

Yes, you do, because containers are movable regardless of their content. As you deduced, st2 will steal the memory from st1. The state of st1 after the move is unspecified though, so I cannot guarantee its storage will have been nullified.

在左值上使用std::move调用push_back()时会发生什么?

When a push_back() is called using std::move on lvalue [what happens] ?

调用左值类型的move构造函数,通常涉及将原始文件按位复制到目标中,然后将原始文件无效.

The move constructor of the type of the lvalue is called, typically this involves a bitwise copy of the original into the destination, and then a nullification of the original.

通常,移动构造函数的成本与sizeof(object)成正比.例如,sizeof(std::string)是稳定的,而不管std::string有多少个字符,因为实际上这些字符存储在堆中(至少在有足够数量的字符时),因此只有 pointer 到堆存储中移动(加上一些元数据).

In general, the cost of a move constructor is proportional to sizeof(object); for example, sizeof(std::string) is stable regardless of how many characters the std::string has, because in effect those characters are stored on the heap (at least when there is a sufficient number of them) and thus only the pointer to the heap storage is moved around (plus some metadata).

这篇关于C ++ 11移动语义行为特定问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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