复制值返回的对象和移动它之间的区别?

Difference between copying the object which was returned by value and moving it?

提问人:Kirill Shvedov 提问时间:10/9/2023 最后编辑:Codemaker2015Kirill Shvedov 更新时间:10/9/2023 访问量:62

问:

我想知道将函数的返回值移动到对象中而不是直接复制它是否有任何意义?std::string

"ip_str“是应该获取 ”“ 返回值的对象:getp1settings()

std::string ip_str = std::move(getp1settings());

下面是“getp1settings”的实现。

std::string SIGDManager::getp1settings() {

    DBAutoConnection connection;
    ...

    std::string p1_virtual;
    if (reader()) {
        reader >> p1_virtual;
    }

    ...

    return p1_virtual;
}

因此,我的问题是将返回值转换为“”的最佳方法是什么(就性能而言)?ip_str

  1. std::string ip_str = std::move(getp1settings());

  2. std::string ip_str = getp1settings();

C++ 优化 move move-semantics

评论

3赞 463035818_is_not_an_ai 10/9/2023
std::move在这里没有效果。 不动,它只是一个石膏,在这种情况下,这种情况是多余的std::move
2赞 Some programmer dude 10/9/2023
我的第一个建议是不要打扰一开始就。通过优化进行构建,并对您的程序进行基准测试/分析。这可能不会出现在前十名的瓶颈列表中,你很少应该做前五名之外的任何事情。std::move
2赞 pptaszni 10/9/2023
在 C++ 中,性能方面的最佳方式通常是编写您的意思并将优化留给编译器
0赞 m2j 10/9/2023
使用 std::move 可以防止 RVO,从而阻止最有价值的优化
3赞 user17732522 10/9/2023
std::move在函数调用中,表达式几乎总是错误的,如果函数返回 by-value,则表达式总是错误的。通常只应在某种变量的名称上使用。std::move

答:

0赞 463035818_is_not_an_ai 10/9/2023 #1

可以并且将从 r 值引用中移动。您不需要强制转换为 r 值引用,因为 r 值引用已经是一个。std::stringstd::movegetp1settings()

评论

1赞 user17732522 10/9/2023
事实上,随着它变得更糟:如果没有它,强制(因为 C++17)复制省略将适用,因为 prvalue 与变量类型相同。因此,不会调用任何复制或移动构造函数。使用复制省略变得不可能,因为现在初始值设定项是一个 xvalue,并且必须调用移动构造函数(除了规则之外)。std::movegetp1settings()std::move
0赞 Yksisarvinen 10/9/2023
@user17732522 RVO 不是这种情况,返回值是命名的,因此它不是必需的优化。但它可能会中断NRVO的可能性。
0赞 user17732522 10/9/2023
@Yksisarvinen 我说的是将返回值复制到 ,而不是从函数内部的局部变量复制到返回值中。或者在 C++ 17 中技术上是正确的:因为函数调用表达式是一个 prvalue 和一个引用的参数,所以为调用 而具体化了一个临时对象。然后从该临时初始化,因为返回对它的引用,同样没有任何复制省略的可能性。ip_strstd::movestd::moveip_strstd::move
0赞 user17732522 10/9/2023
另一方面,当直接从函数调用 prvalue 进行初始化时,变量是操作数中初始化的结果对象,并由它直接初始化。return