问题标签 [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 投票
2 回答
203 浏览

c++ - 从 STL 容器中移动元素是否会将其从该容器中移除?

我有一个Foobar类,其sayHello()方法输出“你好!”。如果我写下面的代码

输出是:

我很困惑为什么这有效。fooList[0]当我做第一步时不应该变成空吗?为什么myFoo2有效?

如下Foobar所示:

0 投票
1 回答
7015 浏览

c++ - 提供正确的移动语义

我目前正在尝试弄清楚如何使用包含指向已分配内存的指针的对象正确移动语义。我有一个大数据结构,其中包含一个指向实际存储的内部原始指针(出于效率原因)。现在我添加了一个 move 构造函数和 move operator=()。在这些方法中,我是std::move()指向新结构的指针。但是我不确定如何处理来自其他结构的指针。

这是我正在做的一个简单示例:

现在根据我的理解,在 iststd::move( s1 )s2唯一可以安全地s1调用它的构造函数之后。但是据我所知,这将导致删除s1析构函数中包含的指针,从而也变得s2无用。所以我猜我必须做一些事情来使析构函数在std::move()ing 指针时安全。据我所知,最安全的做法是将其设置0在移动的对象中,因为这会在delete以后变成无操作。到目前为止,这个推理是否正确?或者std::move()实际上足够聪明,可以为我清空指针,使其使用安全?到目前为止,我在实际的测试套件中没有看到任何崩溃,但我还不确定实际调用了移动构造函数。

0 投票
1 回答
243 浏览

c++ - 异常、移动语义和优化:任由编译器摆布(MSVC2010)?

在对我的旧异常类层次结构进行一些升级以利用 C++11 的一些特性时,我做了一些速度测试,结果有些令人沮丧。所有这些都是使用 x64bit MSVC++2010 编译器完成的,最大速度优化 /O2。

两个很简单struct的,都是按位复制语义。一个没有移动赋值运算符(为什么需要一个?),另一个 - 有。两个简单的内联函数按值返回这些 s 的新创建实例,这些实例struct被分配给局部变量。另外,注意try/catch周围的障碍。这是代码:

程序输出:

两个循环的汇编器(显示周围的计数器调用):

try/catch如果我删除块,两次都是相同的。但是在它存在的情况下,编译器显然可以更好地优化代码,struct以使用冗余移动运算符 =。此外,MakeFoo时间确实取决于大小TFoo及其布局,但总的来说,时间比MakeBar不依赖于小尺寸变化的时间要差几个。

问题

  1. 它是 MSVC++2010 的编译器特定功能(有人可以检查 GCC 吗?)?

  2. 是因为编译器必须在调用完成之前保留临时性,它不能在 的情况下“撕开它” MakeFoo,并且如果MakeBar它知道我们允许它使用移动语义并且它“撕开它”,生成更快的代码?

  3. 我可以在没有try\catch阻塞的情况下,但在更复杂的场景中期望类似的事情有相同的行为吗?

0 投票
2 回答
126 浏览

c++ - C++0x:当一个临时对象等于另一个临时对象时

在本例中,f()g()分别返回一个临时对象,因此f()=g()导致临时对象等于临时对象的表达式。如果正确复制了该值,我会期望答案是 14。但是,它不是调用复制分配,而是调用移动分配!结果,答案不是 14。

这让我真的很困惑。尽管从f()和返回的对象g()是临时的,但它们与其他一些对象共享一些信息。这意味着临时对象可能很快就会为共享信息做一些工作。所以我认为语义上调用复制分配将是正确的行为。

附言。我的编译器是 g++4.7 20110430

0 投票
1 回答
589 浏览

c++ - 这个不可复制的地图是合法的c ++ 11吗?GCC 4.7 和 MSVS 2010 允许它。Clang 3.1 没有

我创建了一个无法用 clang 编译的不可复制的地图。由于 clang 意味着非常符合标准,我想知道我的代码是否合法。MSVS 2010 和 GCC 4.7 编译此代码时不会出现警告或错误。

附上完整代码:有问题的行是main.

= delete需要为 MSVS 2010 移除

使用时的错误信息clang++-mp-3.1 -std=c++0x -stdlib=libc++ MapOfMaps.cpp是:

0 投票
1 回答
1256 浏览

c++ - 对数组的右值引用:它真的会发生吗?

考虑这段代码:

实际上似乎可以编译的唯一版本是ret3(). 实际上,如果我省略了实现并仅声明它,它就会编译(当然永远不会链接),但实际上我不知道如何显式返回对数组的右值引用。如果这不能发生,那么我可以得出结论,对数组的右值引用不是被禁止的,而是不能使用的?

编辑:

我刚刚意识到这有效:

现在有趣的是了解它的实际价值......

0 投票
3 回答
12318 浏览

c++ - 重复使用移动的容器?

重用移动容器的正确方法是什么?

从我在 C++0x 标准草案中读到的内容;ver3 似乎是正确的方法,因为移动后的对象位于

“除非另有说明,否则此类移出的对象应置于有效但未指定的状态。”

我从未发现任何“以其他方式指定”的实例。

虽然我觉得ver3有点迂回,更喜欢ver1,虽然vec3可以允许一些额外的优化,但另一方面很容易导致错误。

我的假设正确吗?

0 投票
1 回答
713 浏览

c++ - 如果从函数返回,局部变量的成员子对象也会被移动吗?

§12.8/31C++11标准规定,如果满足复制省略的条件return(详细,然后将其视为左值(副本)。

§12.8 [class.copy] p32

当满足或将满足复制操作的省略标准时,除了源对象是函数参数的事实,并且要复制的对象由左值指定时,选择复制的构造函数的重载决策是首先执行好像对象是由 rvalue 指定的。如果重载决议失败,或者如果所选构造函数的第一个参数的类型不是对对象类型的右值引用(可能是 cv 限定的),则再次执行重载决议,将对象视为左值。[注:无论是否会发生复制删除,都必须执行此两阶段重载解决方案。它确定如果不执行省略则要调用的构造函数,并且即使调用被省略,所选构造函数也必须是可访问的。——尾注]

这是否还包括成员子对象?我使用以下代码段进行了测试:

Ideone 上的实时示例。 GCC 4.7 ToT 和 Clang 3.1 ToT 都不会显示“move ctor”,这让我相信标准不包括成员子对象。

我忽略了什么吗?我的测试代码坏了吗?究竟是什么导致输出保持原样?

0 投票
2 回答
602 浏览

c++ - C ++中移动语义的起源是什么?

我想知道C++中移动语义的起源是什么?特别是它是专门为这种语言发明的,还是在其他语言中有类似的东西?在后一种情况下,您能否提供一些参考。

0 投票
6 回答
47235 浏览

c++ - 移动赋值运算符和 `if (this != &rhs)`

在类的赋值运算符中,您通常需要检查被分配的对象是否是调用对象,这样您就不会搞砸了:

移动赋值运算符是否需要相同的东西?有没有一种情况this == &rhs会是真的?