2015-04-24 19 views

回答

1

这将取决于处理器的体系结构和编译器的具体实现。

一般来说,返回一个引用可能会使用一个更多的间接引用,所以可能会多用1-2个指令,但这也是一个非常常见的途径,可能会花费一些时间来使其达到最优。

因此,如上所述,您可能需要测量它。 但是,代码中的细微变化可能会改变优化,因此更改结果。作为学术练习,它可能很有趣,但答案是不确定的,其结果很少或根本没有实际用处。

+1

同样,当按值返回时,编译器可以执行复制elision。通过引用返回的 – phantom

+0

通常不是一个好的做法(在局部变量的情况下)。使用右值引用和移位(完美转发)可以完全固定值返回值。 – Sarang

2

一个大对象与深拷贝将是缓慢的价值回归,如果RVO不踢。

但规模并不总是发挥作用。例如,根据平台的不同,返回1字节的对象的速度可能与返回2或4甚至8字节的对象一样快。

很多时候,它并不是关于什么更快,而是使用上下文中需要什么。在一个基元的情况下,当它的意图是输出值的时候,它通常会返回值。当对象身份问题或意图是修改实际对象时,则通过引用返回。

也有可能的限制。例如,你不应该通过引用返回本地函数,因为这是一个等待发生的问题。你可以通过引用返回一个私有成员变量,但是再次,你可以简单地将它公开。

它也取决于“引用返回”的含义,因为这可能是由引用返回的C++样式或由指针返回的C样式。后者更常用,当你在一个函数中动态地分配一个对象并且只是返回一个指向它的指针时,如果是大的或者唯一的对象,那就是要走的路。

此外,除了RVO之外,还有移动语义,这些语义在按值返回时仍会发挥作用。深层副本的开销是C++ 11刚刚解决的一个长期存在的问题。一些像Qt这样的框架通过使用浅拷贝和使用隐式共享资源来解决这个问题。

0

这很大程度上取决于你实际想要返回什么样的价值以及你的功能是什么样子。例如。我们是在谈论abuiltin类型,一个小/大POD,一个阵列或一个非常昂贵的对象 拷贝 移动构造函数?
特别重要的是,如果函数的结构是这样的,那么RVO/NRVO就可以应用。 (命名)返回值优化意味着编译器实际上并不是将局部变量复制到返回值中,而是直接在用于返回值的内存地址构造局部变量。

如果返回值用于在调用站点初始化变量或更改已经初始化的变量的值,这一点也很重要。编译器通常可以优化初始化,但不一定是修改

因此,例如,以下代码:

struct Foo { 
    int a; 
}; 
Foo bar(){ 
    return Foo{ 5 }; 
} 
int main() { 
    Foo = bar(); 
} 

将导致单个Foo对象被构造而不执行任何复制。

除了可能无需复制任何东西(甚至不是一个指针 - 这大概可以通常忽略不计),使用函数的返回值还有一个好处:
编译器可能会在优化更好,因为它不是”交给指针/引用,所以它例如不必担心别名。

所以,如果你返回一个内置类型,或一个小POD,它将明确地使用返回值更好。另一方面,如果您必须更改数组中的值,那么最好使用指向该数组的指针,而不是返回数组,然后将其复制到目标数组中。

在大多数情况下: 这取决于!

0

凭经验: 如果(值是原语) 然后通过价值 否则返回返回参照

如果速度不是问题,总是返回值,你必须少介绍的bug机会那样。

相关问题