2016-12-15 87 views
1

考虑const引用变量初始化

int foo() 
{ 
    return 1; 
} 

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

这两个是const变量初始化之间的差异,包括性能的任何方面?有没有比其他人更喜欢的情况?

+0

“不成熟的优化是万恶的根源” – Slava

+0

@Slava这整个语言都是关于微观优化的。 – grisevg

+0

@grisevg我不同意。首先,不正确的程序速度有多快并不重要。所以首先是可读性,然后是微型化,并且只在必要的地方。 – Slava

回答

0

const auto v1 = foo()

这会创建一个const变量v1。如上所述创建意味着任何foo()返回现在都保持在v1中。

const的汽车& V2 = FOO()

是一个const的引用,以便FOO()应返回的参考。如果任何foo()返回不支持移动语义const auto & v2会更快。

P.S.在你的情况下,因为foo()返回一个int,所以不会有问题。

+0

正如我在回答中所说的那样,在这种情况下'const auto&v2 = foo()'是非常危险的,应该避免,除非你想利用一个临时的延长生命周期并且很好地理解它是如何工作的。 – grisevg

+1

在v2超出范围之前,const引用的临时变量不会被销毁。检查这个更多细节https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ –

-1

我会小心,并避免const引用临时(链接https://herbsutter.com/2008/01/01/gotw-88-a-c....赞美A.N.)。它可以很容易地更改为auto &v2 = foo();这是未定义的行为。

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

我并不是说永远不会通过const引用来延长临时对象的生命周期,我相信可能存在有用的用例,例如当NRVO无法完成时,我所说的就是避免除非有很好的理由。这不是很知名的功能,它可能会导致危险的代码。

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

+0

那么为什么VS2012甚至不会发出警告呢? – user6386155

+1

没有一个编译器会抱怨,因为它是一个常量。检查这个https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ –