计算来自f(foo)的哪些转换;foo.~foo()到f(std::move(foo));foo.~foo()在性能方面或内存消耗方面都是有利可图的,同时遵守C++规范规则。 概念Read,2017年C++编译器,如GCC 3.3.0,是强>能够优化< /强>此代码: Foo meh() { Foo foo(args); foo.method(xyz); bar(); return foo; } void meh(Foo *retval) { new (retval) Foo(arg); retval->method(xyz); bar(); }

计算来自f(foo)的哪些转换;foo.~foo()到f(std::move(foo));foo.~foo()在性能方面或内存消耗方面都是有利可图的,同时遵守C++规范规则。 概念Read,2017年C++编译器,如GCC 3.3.0,是强>能够优化< /强>此代码: Foo meh() { Foo foo(args); foo.method(xyz); bar(); return foo; } void meh(Foo *retval) { new (retval) Foo(arg); retval->method(xyz); bar(); },c++,c++11,move-semantics,C++,C++11,Move Semantics,在此代码中: Foo meh() { Foo foo(args); foo.method(xyz); bar(); return foo; } void meh(Foo *retval) { new (retval) Foo(arg); retval->method(xyz); bar(); } 这样可以避免调用Foo的复制构造函数和析构函数 2017年C++编译器,如GCC 3.3.0,不能优化这些代码: Foo meh_value

在此代码中:

Foo meh() {
    Foo foo(args);
    foo.method(xyz);
    bar();
    return foo;
}
void meh(Foo *retval) {
   new (retval) Foo(arg);
   retval->method(xyz);
   bar();
}
这样可以避免调用
Foo
的复制构造函数和析构函数


2017年C++编译器,如GCC 3.3.0,<强>不能优化这些代码:

Foo meh_value() {
    Foo foo(args);
    Foo retval(foo);
    return retval;
}

Foo meh_pointer() {
    Foo *foo = get_foo();
    Foo retval(*foo);
    delete foo;
    return retval;
}
Foo meh_value() {
    Foo foo(args);
    Foo retval(std::move(foo));
    return retval;
}

Foo meh_pointer() {
    Foo *foo = get_foo();
    Foo retval(std::move(*foo));
    delete foo;
    return retval;
}
在这些代码中:

Foo meh_value() {
    Foo foo(args);
    Foo retval(foo);
    return retval;
}

Foo meh_pointer() {
    Foo *foo = get_foo();
    Foo retval(*foo);
    delete foo;
    return retval;
}
Foo meh_value() {
    Foo foo(args);
    Foo retval(std::move(foo));
    return retval;
}

Foo meh_pointer() {
    Foo *foo = get_foo();
    Foo retval(std::move(*foo));
    delete foo;
    return retval;
}


这意味着2017年的程序员需要明确指定此类优化。

当您使用Visual Studio时。仅供参考,在第二种情况下,当您从函数返回时,您不能再拥有任何指向foo的可用引用/指针。您对返回的值做了什么<代码>Foo f=meh()已经在C++98中使用了(N)RVO。我想知道显式调用std::move是否会阻止NRVO…
std::move
是一个标识操作。它实际上什么都不做。它只是右值的标记。如果编译器手头有
Foo
的move构造函数,它可以查看它是否有可观察的效果,并决定是否有。如果它没有明显的效果,你怎么能分辨出区别呢?最后一段的注释是错误的。编译器需要将其视为右值。@R.MartinhoFernandes Yes和no,它将被视为右值,但我的编译器更喜欢省略来移动构造,因此可以说没有移动语义(因为根本不会调用移动构造函数)。第一段是错的。返回
std::move
几乎总是一个坏主意,但在某些情况下,返回
std::move
是正确的做法。使用
std::move
被认为是有害的,可以防止删除更正:对被认为有害的返回值使用std::move,可以防止删除C++:bone simple。显然。C++:如果你不笑,你会哭。当函数声明返回
std::unique_ptr
时,尝试返回声明为
std::unique_ptr
的变量怎么样?在gcc和mingw-w64中,它只起作用,但vanilla mingw(基于gcc 4.9.3,目标是
i686 pc cygwin
)需要
std::move(x)
来编译。@rr:不确定。在这种情况下,我希望需要
std::move
(因为类型不匹配,所以复制省略是不可能的),但我可能忽略了一些东西。32位和64位mingw之间的差异是奇怪的。我想不出为什么编译器或平台作者会这么做。谢谢,这是有道理的。简单地说,mingw-w64不仅仅是mingw的64位版本,它是一个引入了一些实质性更新的fork。应该注意的是,如果在适当的位置创建了三元组的一个参数,它将直接构造到返回变量中。然而,采取行动将防止这种情况。这使得第二种选择更加灵活-一种只移动命名的arg。在
int
上使用
std::move
没有任何好处;如果
x
是一个具有昂贵副本(例如附加到字符串)的类类型@M.M,则这可能是一个更好的示例accepted@M.M在这个例子中,我不太关心C++术语。答案中的“调用std::move”一词的含义相当于“使用std::move”。@M.M您对如何改进答案有进一步的建议吗?@atomsymbol这是一个很好的信息性答案,补充了现有答案,我不知道这是怎么回事。
Foo meh_value() {
    Foo foo(args);
    Foo retval(std::move(foo));
    return retval;
}

Foo meh_pointer() {
    Foo *foo = get_foo();
    Foo retval(std::move(*foo));
    delete foo;
    return retval;
}