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

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

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

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

4

2 回答 2

5

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

请参阅此实时工作空间警告消息。当您执行此类操作时,您的编译器通常会警告您,但并不总是建议您依赖它。

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

于 2013-04-15T22:19:00.100 回答
1

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

例如,如果您的foo函数是类的成员函数,并且正在返回对该类成员的引用,那就没问题了:

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

在上面的示例中,它比不创建任何新对象foo1更有效foo2,只返回对现有对象的引用。

于 2013-04-15T22:24:10.760 回答