0

考虑以下返回大对象的函数:

std::list<SomethingBig> DoSomething()
{
    std::list<SomethingBig> TheList;
    //do stuff
    return TheList;
}

我想得到清单,而不是它的副本。因为如果我必须复制这样的对象,性能代价是昂贵的。我知道返回值优化可能会为我解决这个问题,但是依靠优化来优化坏代码并不是最好的方法(对吧?)。

避免复制和延长对象寿命的一种干净方法是使用常量引用(请在将其称为悬空引用之前对其进行测试,因为它不是):

const std::list<SomethingBig>& theList = DoSomething();

在 C++11 中,可以std::move用来避免复制。但是,我正在开发一个 C++03 程序,我必须这样做:

const std::list<SomethingBig>& list1 = DoSomething();
const std::list<SomethingBig>& list2 = DoSomethingElse();

现在我需要将列表拼接在一起。我这样做的唯一方法是复制所有内容,或者const_cast这些列表并将它们拼接起来。有更好的解决方案吗?

4

2 回答 2

1

只需按值返回它,它会比引用和std::move由于 NRVO 更好,这不是“对坏代码的优化”,而是一种让好代码快速工作的方法。

据我所知,NRVO 确实不能保证会发生(与 RVO 不同,自 c++17 以来这将是必须的),但编译器不太可能不会在此处省略副本。

无论如何,依靠复制省略比使用const_cast技巧要安全得多,而且比移动便宜。

clang 和 gcc 都删除了副本-std=c++03 -O0

于 2017-04-05T11:37:43.320 回答
0

改变接口的DoSomething...()tostd::list<SomethingBig> & DoSomething(std::list<SomethingBig> &)怎么样?列表对象的生命周期将在 和 之外进行DoSomething()控制DoSomethingElse()。例如:

std::list<SomethingBig> list;
DoSomethingElse(DoSomething(list));
于 2017-04-05T14:49:21.690 回答