问题标签 [move-semantics]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
5 回答
659 浏览

c++ - 如何使用移动的对象?

移动对象后,它必须是可破坏的:

但是 obj 还能做什么呢?你能把另一个物体移进去吗?

这取决于确切的类型吗?(例如,std::vector 可以为所有 T 做出你不能依赖的特定保证。)除了对移动对象的破坏之外,所有类型是否都支持某些东西是必需的,甚至是理智的?

0 投票
4 回答
1538 浏览

c++ - 移动地图的构造函数

我想我确实了解移动语义的“基本思想”,但是现在当我在实现自己的地图的阶段时,当我要编写一个用例并遍历移动时,我停下来开始思考它地图的ctor。如果我错了,请纠正我,但我确实理解移动语义的整个业务是如何工作的,他们认为它们有助于避免不必要的复制?对?现在,以地图为例,仅出于本示例的目的,假设我的地图建模为:

这是障碍:当我试图为我的地图考虑移动 ctor 时,我看不到一种方法可以避免为所有需要创建的链接分配新空间,然后将它们的指针与 tmp 地图中的指针交换对象(作为 arg 传递给我的移动 ctor)。
所以无论如何我都必须分配空间,不是吗?

0 投票
2 回答
299 浏览

c++ - 调用基类移动 ctor [C++0x]

哪个是调用基类移动ctor的正确方法?

这(在 MSVC2010 中有效,但在 CBuilder2010 中无效):

或(在 CBuilder2010 中有效,但在 MSVC2010 中无效):

或者,他们都错了吗?如果是这样,正确的方法是什么(根据 C++0x 标准中的规定)?

注意:我不知道如何让它在 CBuilderXE 中工作(两个版本都不起作用)。

0 投票
2 回答
2803 浏览

c++ - std::move 之后的僵尸对象

我对使用 C++0x 移动语义移动对象后的状态感到困惑。我的理解是,一旦一个对象被移动,它仍然是一个有效的对象,但是它的内部状态已经改变了,所以当它的析构函数被调用时,没有资源被释放。

但是如果我的理解是正确的,移动对象的析构函数仍然应该被调用。

但是,当我执行一个简单的测试时,这不会发生:

这个输出:

注意析构函数只被调用一次。这表明我在这里的理解是错误的。为什么没有调用两次析构函数?这是我对应该发生的事情的解释:

  1. Foo f1被构造。
  2. Foo f1被传递给work,它接受一个 rvalue f2
  3. Foo调用移动构造函数,将所有资源移动f1f2.
  4. Nowf2的析构函数被调用,释放所有资源。
  5. Nowf1的析构函数被调用,它实际上并没有做任何事情,因为所有资源都被转移到了f2. 尽管如此,还是调用了析构函数。

但是由于只调用了一个析构函数,因此第 4 步或第 5 步都不会发生。我从析构函数进行了回溯,以查看它是从哪里调用的,并且它是从第 5 步调用的。那么为什么不调用f2' 析构函数呢?

编辑:好的,我修改了这个,所以它实际上是在管理一个资源。(一个内部内存缓冲区。)不过,我得到了与只调用一次析构函数相同的行为。

0 投票
3 回答
20288 浏览

c++ - 在派生对象上移动构造函数

当您有一个带有移动构造函数的派生对象,并且基础对象也具有移动语义时,从派生对象移动构造函数调用基础对象移动构造函数的正确方法是什么?

我首先尝试了最明显的事情:

但是,这似乎最终调用了 Base 对象的复制构造函数。然后我尝试std::move在这里明确使用,如下所示:

这行得通,但我很困惑为什么它是必要的。我以为std::move只是返回一个右值引用。但是因为在这个例子rval中已经是一个右值引用,所以调用std::move应该是多余的。但是如果我不在std::move这里使用,它只是调用复制构造函数。那么为什么std::move需要调用呢?

0 投票
2 回答
15311 浏览

c++ - 将移动语义与 std::pair 或 std::tuple 一起使用

假设您想利用移动语义,但您的一个可移动类需要是std::pair. 目的是创建一个函数,该函数返回一个std::pair可以被视为右值并转发的函数。

但是我看不到如何做到这一点,除非对其std::pair自身进行内部更改,以使其了解移动语义。

考虑以下代码:

问题是std::make_pair,以及std::pair构造函数本身,需要两个对象并尝试制作它们的内部副本。这会导致它尝试调用复制构造函数。但在我的示例中,我希望能够将新对移动到res,并确保不制作任何副本。我认为这是不可能的,除非std::pair它本身在内部定义了以下构造函数:

但它没有,至少在我使用的编译器(gcc 4.3.2)上没有。可能是我的编译器只是过时了,而实际上较新的版本具有此移动感知构造函数。但是目前我对移动语义的理解有些不稳定,所以我不确定我是否只是在这里忽略了一些东西。那么,在没有实际重新实现的情况下,我想要实现的目标是否可行std::pair?还是我的编译器刚刚过时?

0 投票
1 回答
1720 浏览

c++ - 在容器之间移动一系列元素?

我一直在查看 C++ 文档中的一个函数,该函数使用移动语义将一系列元素从一个容器移动到另一个容器。但是,我还没有找到这样的功能。我错过了什么?

如果不复制和使用显式循环,我将如何执行以下操作?

0 投票
2 回答
2573 浏览

c++ - 将范围拆分为子范围

我有一个容器 std::vector ,我想有效地将​​它分成子范围,每个子范围都有 x 项。不需要原始容器,因此应移动项目而不是将其复制到子范围中。

我已经设法使用复制进行拆分,但是我不确定如何使用移动分配进行拆分?

编辑:

一些进展......仍然不完全在那里,而且有点难看

0 投票
4 回答
14441 浏览

c++ - 这是 C++“移动”语义的正确用法吗?

今晚我一直在看一些我过去几天一直在处理的代码,并开始阅读移动语义,特别是 std::move。我有几个问题要问你们专业人士,以确保我走在正确的道路上,而不是做出任何愚蠢的假设!

首先:

1)最初,我的代码有一个返回大向量的函数:

鉴于“theVector”在此是临时的并且“丢弃”,我将函数修改为:

这个对吗?这样做有什么陷阱吗?

2)我注意到我有一个函数返回std::string它自动调用移动构造函数。调试到返回字符串(谢谢,Aragorn),我注意到它称为显式移动构造函数。为什么有一个字符串类而不是向量?

我无需对此函数进行任何修改即可利用移动语义:

3)最后,我想做一些性能测试,是因为 std::move 语义而得到的惊人的快速结果还是我的编译器(VS2010)也做了一些优化?

_getMilliseconds()为简洁起见省略的实现)

结果显然很棒。result1 是一个标准作业,耗时 630 毫秒。第二个结果是 0ms。这是对这些东西的良好性能测试吗?

我知道其中一些对你们很多人来说是显而易见的,但我想确保在我对我的代码进行更深入的研究之前了解语义。

提前致谢!

0 投票
2 回答
550 浏览

c++ - 我是唯一一个觉得 std::move 有点难以理解的人吗?

所以我一直在 SO 和其他地方阅读关于std::move, std::forward, rvalues, lvalues ad 等等。但我发现我无法掌握它。尽管我有时会进行修复,但我想我了解在这之前 C++ 中有关指针、引用等的基本知识。是我还是这些东西太重了?