【问题标题】:const reference variable initializationconst 引用变量初始化
【发布时间】:2017-05-01 06:13:34
【问题描述】:

考虑

 int foo()
 { 
  return 1;
 }

 main()
 {
   const auto v1 = foo();
   const auto &v2 = foo();
 }

这两个const变量初始化有什么区别,包括性能在内的任何方面?有没有一种情况会偏爱别人?

【问题讨论】:

  • “过早的优化是万恶之源”
  • @Slava 这整个语言都是关于微优化的。
  • @grisevg 我不同意。首先,不正确的程序有多快是绝对不重要的。因此,首先是可读性,然后是微优化,并且仅在必要时进行。

标签: c++ visual-studio-2012 reference initialization constants


【解决方案1】:

const auto v1 = foo()

这将创建一个 const 变量 v1。如前所述,创建意味着 foo() 返回的任何内容现在都保留在 v1 中。

const auto &v2 = foo()

是对 const 的引用,因此 foo() 应该返回一个引用。如果 foo() 返回的内容不支持移动语义,则 const auto &v2 会更快。

附:在你的情况下,因为 foo() 返回一个 int 并不重要。

【讨论】:

  • 正如我在回答中所说,在这种情况下 const auto &v2 = foo() 非常危险,应该避免使用,除非您想利用临时的延长生命周期并很好地了解它的工作原理.
  • 在 v2 超出范围之前,const 引用的临时变量不会被销毁。检查此以获取更多详细信息herbsutter.com/2008/01/01/…
【解决方案2】:

我会小心并避免 const 引用临时(感谢 A.N. 链接 https://herbsutter.com/2008/01/01/gotw-88-a-c....)。稍后可以轻松将其更改为 auto &v2 = foo();,这是未定义的行为。

Scott Meyers 和 Herb Sutter 确实建议返回按值在堆栈上创建的对象。您可以利用命名返回值优化 (NRVO) 来确保最佳性能,实际上这将比 returnig 引用临时或使用移动语义更快。

我并不是说永远不要通过 const 引用来延长临时对象的生命周期,我确信在某些用例中它是有意义的,例如当 NRVO 无法完成时,我所说的只是避免它除非有充分的理由。这不是众所周知的功能,它可能会导致危险代码。

更新:更正了 const auto &v2 = foo(); 实际上是有效代码,但添加了为什么仍然应该避免使用它的解释。还添加了描述 NRVO 的链接。

【讨论】:

  • 那为什么VS2012甚至不发出警告呢?
  • 没有一个编译器会抱怨,因为它是一个常量。检查这个herbsutter.com/2008/01/01/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
  • 2017-09-21
  • 2014-09-08
  • 2021-10-19
相关资源
最近更新 更多