将引用定义为函数调用 - 有什么好处?

Defining a reference as a function call - what are the benefits?

本文关键字:什么 引用 定义 函数调用      更新时间:2023-10-16

我遇到了如下所示的代码:

std::vector<foo> someFunction(Args args)
{
std::vector<foo> value;
/*...*/
return value;
}
std::vector<foo> someOtherFunction(OtherArgs args)
{
std::vector<foo> value;
/*...*/
return value;
}
const auto bar = someFunction(args);
const auto& rBar = someOtherFunction(otherArgs);

我想知道这些是参考文献是否有任何显着差异。我使用计时器测试了这两个变量的性能,没有发现结果有任何显着差异,并且这两个变量的行为方式似乎完全相同,至少在表面上是这样。

其中之一是否更可取,如果是,为什么?撇开一致性争论不谈。

抱歉,如果标题不清楚,我真的不知道该怎么称呼它。

进一步挖掘

我在Visual Studio 2015(MSVC v140(中检查了这两行的反汇编,发现:

非参考:

mov    edx,20h
lea    rcx,[vec]
call   std::vector<int, std::allocator<int> >::__autoclassinit2
lea    rcx,[vec]
call   someFunction
nop

参考:

lea    rcx[rbp+88h]
call   someFunction
nop
lea    rax,[rbp+88h]
mov    qword ptr [rVec],rax

不幸的是,我的组装傅远不足以准确理解这里发生的事情。

我想知道这些引用是否有任何显着差异。

不。

第一个只是初始化一个对象变量。

第二个初始化一个临时对象,并将该对象绑定到引用。临时的生存期延长至引用的生存期(通常临时项只存在到完整表达式结束(。

最后,一旦程序被优化,就没有任何区别。

是其中之一

是的。const auto bar = someFunction(args);

为什么?

因为它更简单,因此更容易理解。作为奖励,它也较少写。

在您的情况下,性能和含义相似。

区别主要是

  • "可读性":

    我们不用看someFunction声明就知道bar已经构造好了,而不是引用/别名。因此,其他不相关的功能不能改变bar但可以间接改变rBar
    (指向bar(。

  • 未来更改的行为:

    如果函数更改为返回 (const( 引用,bar会复制,而rBar则不这样做rBar