【发布时间】:2012-08-30 10:20:44
【问题描述】:
我正在努力学习足够好的移动语义,以便将其介绍给我的学生。我一直在使用高度简化的向量或类似字符串的类来管理内存,并且其成员输出消息以展示它们的活动。我正在尝试开发一组简单的示例来向学生展示。
gcc 4.7 中 RVO 和其他地方的构造省略和 clang 积极地消除了复制和移动构造,所以虽然我可以很容易地在工作中看到移动分配,但我唯一一次在工作中看到移动构造是如果我关闭构造省略在带有 -fno-elide-constructors 的 gcc 4.7 中。
显式复制构造语句
MyString newString(oldString);
即使启用了省略,也会调用复制构造函数。但是像
MyString newString(oldString1 + oldString2);
由于省略,不调用移动构造函数。
任何显式使用 std::move 的东西都不会是一个简单的例子,因为解释 std::move 必须在后面。
所以我的问题是:是否有一个简单的代码示例可以调用移动构造,即使复制/移动构造函数被省略?
【问题讨论】:
-
我不确定没有
std::move... -
"任何显式使用 std::move 的东西都不会是一个简单的例子,因为解释 std::move 必须在后面。" 嗯,为什么?
std::move是明确移动事物的方式。移动支持主要是关于显式 移动,因为大多数隐式移动都可以通过省略来捕获。通过向他们隐藏move,您正在对任何从中学习的人造成伤害。 -
@NicolBolas:因为有隐含的动作,至少在理论上是这样。想想 OP 要求中间级别的优化:
oldString1+oldString2触发一个副本(这里没有优化),但副本被移动到newString(优化)。实际上,这很难触发,因为编译器选择了“复制省略”优化而不是“移动复制”优化(有充分的理由)。 -
我将不得不解释 std::move,但如果我能够演示移动构造而无需先介绍 std::move(其解释有点棘手),这将有所帮助。
-
@NicolBolas - 抱歉,我应该在上面的评论前面加上前缀,以表明我的评论是对你的回应。
标签: c++ c++11 move-semantics