关于通过引用返回值的c ++难题

时间:2013-04-15 22:16:22

标签: c++ reference

set<string> foo {
  set<string> a;
  // operation on a
  return a;
}

如果我这样做有任何性能差异:

set<string>& foo {
  set<string> a;
  // ops on a
  return a;
}

如果是这样,我的理解是将在堆栈上分配。 foo()返回后, 内存空间将被回收。我们如何引用所声称的记忆?

2 个答案:

答案 0 :(得分:5)

在B情况下,任何实际使用返回值都会导致未定义的行为。您不能通过引用返回本地自动变量,并希望任何人都能够访问它。

请参阅此live work space警告消息。当你做这样的事情时,你的编译器通常会警告你,但并不总是建议依赖它。

请注意,在C ++ 11中,第一个示例非常高效。在基于左值参考的移动和NRVO之后,按值返回本地std::vector<std::string>的成本大约为几个ifs并复制32位内存,或者在某些情况下更少(即实际上为零成本,因为std::set直接在调用者范围内构建。

答案 1 :(得分:1)

没有必要讨论一个不正确的代码的性能,比如你的第二个片段,这个行为是未定义的(这通常会使你的程序崩溃)。您不能返回对函数本地的自动对象(在堆栈上分配)的引用。

例如,如果你的foo函数是一个类的成员函数,并且正在返回对该类成员的引用,那就没关系了:

class C {
public:
  set<string>& foo1 { return a_; }
  set<string> foo2 { return a_; }
private:
  set<string> a_;
}

在上面的例子中,foo1foo2效率更高,因为它不会创建任何新对象,只需返回对现有对象的引用。