它是更好的在C + +传递值或通过常量引用? [英] Is it better in C++ to pass by value or pass by constant reference?

查看:147
本文介绍了它是更好的在C + +传递值或通过常量引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++中传递值或传递常量引用会更好吗?



我想知道哪个是更好的做法。我意识到通过常量引用应该提供更好的性能在程序中,因为你不是一个变量的副本。

解决方案

它通常是建议的最佳实践 1 use pass by const ref除了内置类型( char int double 等),对于迭代器和函数对象(lambdas,派生自 std :: * _ function



这在移动语义存在之前尤其真实。原因很简单:如果你通过值传递对象的副本,除非是非常小的对象,这总是比传递引用更昂贵。



使用C ++ 11,我们获得了 移动语义 。简而言之,move语义允许在某些情况下,对象可以按值传递而不复制它。特别是,当您传递的对象是 右值 时,就是这种情况。 / p>

本身,移动对象仍然至少像通过引用传递一样昂贵。但是,在许多情况下,函数将在内部复制对象 - 即它将占用参数的所有权 2



在这些情况下,我们有以下(简化)折衷:


  1. 我们可以通过引用传递对象, 。

Pass by value仍然会导致要复制的对象,除非对象是右值。在右值的情况下,可以移动对象,使得第二种情况突然不再复制,然后移动而是移动,然后(可能)再次移动。



对于实现正确的移动构造函数(例如向量,字符串...)的大对象,第二种情况比第一种更有效。 因此,如果函数拥有参数的所有权,并且对象类型支持高效移动,则建议使用pass by value。






历史记录:



事实上,任何现代编译器都应该能够知道当传递的值是否昂贵,如果可能,则隐式转换调用以使用const引用。



在实践中,编译器不能总是改变它,函数的二进制接口。在一些特殊情况下(当函数被内联时),如果编译器能够知道原始对象不会通过函数中的动作被改变,那么副本将被省略。



但是一般来说,编译器不能确定这一点,而且C ++中移动语义的出现使得这种优化变得不那么重要了。






1 例如



2 对于构造函数来说,这通常是真的,并将它们内部存储为构造对象状态的一部分。


Is it better in C++ to pass by value or pass by constant reference?

I am wondering which is better practice. I realize that pass by constant reference should provide for better performance in the program because you are not making a copy of the variable.

解决方案

It used to be generally recommended best practice1 to use pass by const ref for all types, except for builtin types (char, int, double, etc.), for iterators and for function objects (lambdas, classes deriving from std::*_function).

This was especially true before the existence of move semantics. The reason is simple: if you passed by value, a copy of the object had to be made and, except for very small objects, this is always more expensive than passing a reference.

With C++11, we have gained move semantics. In a nutshell, move semantics permit that, in some cases, an object can be passed "by value" without copying it. In particular, this is the case when the object that you are passing is an rvalue.

In itself, moving an object is still at least as expensive as passing by reference. However, in many cases a function will internally copy an object anyway — i.e. it will take ownership of the argument.2

In these situations we have the following (simplified) trade-off:

  1. We can pass the object by reference, then copy internally.
  2. We can pass the object by value.

"Pass by value" still causes the object to be copied, unless the object is an rvalue. In the case of an rvalue, the object can be moved instead, so that the second case is suddenly no longer "copy, then move" but "move, then (potentially) move again".

For large objects that implement proper move constructors (such as vectors, strings …), the second case is then vastly more efficient than the first. Therefore, it is recommended to use pass by value if the function takes ownership of the argument, and if the object type supports efficient moving.


A historical note:

In fact, any modern compiler should be able to figure out when passing by value is expensive, and implicitly convert the call to use a const ref if possible.

In theory. In practice, compilers can’t always change this without breaking the function’s binary interface. In some special cases (when the function is inlined) the copy will actually be elided if the compiler can figure out that the original object won’t be changed through the actions in the function.

But in general the compiler can’t determine this, and the advent of move semantics in C++ has made this optimisation much less relevant.


1 E.g. in Scott Meyers, Effective C++.

2 This is especially often true for object constructors, which may take arguments and store them internally to be part of the constructed object’s state.

这篇关于它是更好的在C + +传递值或通过常量引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆