问题标签 [stdmove]

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 投票
1 回答
116 浏览

c++ - 在按值返回的函数的 return 语句中初始化

我的问题源于对std::moveinreturn语句的深入研究,例如以下示例:

打印 (MSVC, /std:c++17, release)

我对按值返回的函数中返回语句的一般初始化规则以及在返回局部变量时适用哪些规则感兴趣,std::move如上所示。

一般情况

关于退货声明,您可以阅读

  1. 计算表达式,终止当前函数,并在隐式转换为函数返回类型后将表达式的结果返回给调用者。[...]

在 cppreference.com 上。

其中复制初始化发生

  1. 当从一个按值返回的函数返回时

回到我的例子,根据我目前的知识 - 与上述规则相反 -A a1(nrvo());是一个使用 prvalue直接初始化nrvo()a1 的语句。那么,如 cppreference.com 中针对返回语句所述,哪个对象被复制初始化了呢?

std::move案例_

对于这种情况,我参考了 ipc 关于Are returned locals automatically xvalues的回答。我想确保以下内容是正确的:std::move(local)具有类型A&&no_nrvo()被声明为返回类型A,所以这里

将表达式的结果隐式转换为函数返回类型后返回给调用者

部分应该发挥作用。我认为这应该是左值到右值的转换

任何非函数、非数组类型 T 的泛左值都可以隐式转换为相同类型的纯右值。[...] 对于类类型,此转换 [...] 将 glvalue 转换为 prvalue,其结果对象由 glvalue 复制初始化。

使用to convert from A&&toA A的移动构造函数,这也是这里禁用 NRVO 的原因。这些规则是否适用于这种情况,我是否理解正确?此外,他们再次说由 glvalue复制初始化A a2(no_nrvo());,但它是直接初始化。所以这也涉及到第一种情况。

0 投票
1 回答
78 浏览

c++ - 对纯右值调用的 std::move 是否解构对象?

我已经编写了这样的代码,该代码适用std::move于临时构造函数中的纯右值。

打印效果是这样的(print也在构造函数和析构函数中):

stackoverflow中的一些问题说第一种情况应该没有影响,我想知道我的代码会发生什么。那是Obj(1, "lost")在函数中作为参数并在退出std::move时死亡吗?std::move

0 投票
1 回答
55 浏览

c++ - 从 std::list 中的元素的 std::move 后得到无效输出

我试图了解 std::move。在我的代码中,我正在从内部包含两个字段的std::list<struct Data>位置移动一个元素,但我没有得到预期的输出。这是我的代码:struct Datastd::string

0 投票
2 回答
91 浏览

c++ - 在函数上调用 std::move 时会做什么?

我正在对一段代码进行一些更改,并且在以下情况下对理解 std::move 的行为有疑问:

A的构造函数:

回调函数定义:

main(),

我的疑问是这一行: A::A (std::function<void(Timer *, const TimerContext&)> cb) : callback_{std::move(cb)}

A 类在循环中被实例化,并且相同 customCallback的函数被移动到每个新对象的自定义构造函数中。

第一个 std::move 不会使回调函数无法用于下一次调用吗?据我了解,如果您使用std::move(t), 则t不能在该范围内再次使用。

我很困惑std::move(cb)new A. 这是执行它的正确方法吗?

0 投票
0 回答
37 浏览

c++11 - 为什么移动分配 std::vector 似乎没有比在此代码中复制有任何性能优势?

由于移动分配 std::vector 是一个O(1)时间操作,而将 std::vector 复制到另一个是O(N)(其中 N 是 2 个向量的大小之和),我希望看到移动分配具有显着的性能比抄袭更有优势。nums2为了测试这一点,我编写了以下代码,它将大小为 1000 到nums100,000 次的 std::vector 移动分配/复制。

我使用的编译器是 g++ 7.5.0。使用 运行时g++ -std=c++1z -O3,移动分配/复制版本都需要大约 1600 毫秒,这与移动分配具有任何显着性能优势的假设不符。然后我测试了使用std::swap(nums, nums2)(作为移动分配的替代方法),但这也花了大约相同的时间。

所以,我的问题是,为什么将 std::vector 移动分配给另一个似乎比复制分配具有性能优势?我对 C++ 移动赋值的理解是否存在根本性错误?

0 投票
1 回答
61 浏览

c++ - 使用值包含 unique_ptr 成员变量的初始值设定项列表

我有一个包含 unique_ptr 的类。我想将此类的实例放在容器中(特别是 std::map)。这可以使用std::move.emplace但是,我想在容器的初始化列表中执行所有这些初始化。这可能吗?

我怀疑Foo在初始化列表中被初始化,然后被复制,这导致了问题。我尝试std::move在初始化列表中添加一个,但这并没有解决问题。

编译失败“试图访问已删除的函数”。这是我想做的一个例子

编译成功

0 投票
1 回答
83 浏览

c++ - 混合右值和左值引用

我试图更好地理解 LValue、RValue 以及 std::move 的工作原理。我有以下代码

我的问题是:

  • void InitMembers(string& aString) { myA = A(std::move(aString));}我所知,我必须使用 std::move 到 aString 才能将 aString 从 LValue 引用转换为 RValue 引用。但是我对 InitMember 范围内的 aString 的含义有些怀疑。aString 作为 LValue 引用提供,但在方法范围内它被视为 LValue,这就是为什么我必须使用 std::move? Std::move 应该依赖于引用推导(对吗?),在这种情况下它如何推导类型?它会推导出一个类型“字符串”或“字符串&”,因为 aString 是作为方法参数中的 LValue 引用提供的?
  • 为什么我还必须在 A 的构造函数初始化程序中使用 std::move?aString 是触发移动构造函数的 RValue 引用这一事实还不够吗?

下面的实现不是和上面的一样好吗?

谢谢 :)

0 投票
2 回答
90 浏览

c++ - 返回 std::move 具有 unique_ptr 成员的类

std::unique_ptr为什么我不能使用语义(我认为)返回包含 a 的类std::move,如下例所示?我认为返回会调用 class 的 move ctor ,A而. (我使用的是 gcc 11.2,C++20)std::movestd::unique_ptr

例子:

我相信解决方案是返回 a std::unique_ptr,但在我放弃之前,我想知道为什么 move 方法不起作用。

0 投票
0 回答
33 浏览

c++ - 使用链表实现堆栈(使用模板、左值和右值引用、通用引用、完美转发)

我最近学习了左值和右值引用、通用引用、完美转发、std::move()、std::forward() 等概念。

我尝试实现 Stack 的模板化版本(使用链接列表)并且想知道如何在我的程序中正确有效地使用上述概念。

我希望利用移动语义

注意:我自己确实尝试过这样做,但似乎没有正确解决! 我在我认为可以的地方评论了//possible use并尝试自己使用上述概念!

我不会提及我的混乱代码版本,因为我觉得它太错误了。相反,如果有人可以在我的原始代码中指导或帮助我,我将不胜感激。任何反馈表示赞赏!

编辑: 1. 我可以像这样使用 Rvalue 参考:-

但是,如果我希望传递 Lvalues,我将不得不std::move()在调用push()函数时使用,但我希望我的Stack类保持一个黑盒,这样用户就不必担心使用移动语义......我的类应该通过利用移动语义,仍然可以以最有效的方式工作。

0 投票
1 回答
50 浏览

c++ - 从临时对象的数据成员中正确移动

考虑以下 C++ 代码

与输出

从成员中移出的正确方法是WrapMe:like Wrapper1(return by value) 还是 like Wrapper2(return by rvalue-reference) 呢?或者,正如输出所暗示的那样,这两种方式在这里是等价的?如果不是,为什么?