简体   繁体   English

如何在 C++ 中通过引用传递“文字”整数

[英]How to pass "literal" integers by reference in C++

To avoid the inefficiency of copy-by-value when calling a function (say, "fillRect"), I want to pass the parameters by reference.为了避免在调用 function(比如“fillRect”)时按值复制的低效率,我想通过引用传递参数。

If I supply the parameters as declared local variables, it works fine.如果我将参数作为声明的局部变量提供,它就可以正常工作。 But if I supply any as "literal" integers, I get a compile error (no matching function).但是如果我提供任何作为“文字”整数,我会得到一个编译错误(没有匹配的函数)。

void fillRect( int &x, int &y, int &width, int &height )
{
    // do something
}

int x=10, y=20, w=100, h=80;

fillRect(x, y, w, h); // this compiles and works!
fillRect(x, y, 100, 80); // but this doesn't compile ... why?

What gives?是什么赋予了?


(Forgive my naivety: I'm pretty new to C++.) (原谅我的天真:我是 C++ 的新手。)

As many people have pointed out, pass-by-reference isn't generally appropriate as an optimisation for primitive types.正如许多人指出的那样,按引用传递通常不适合作为基本类型的优化。 This is excellent to know, so thank you all, Even so, my question was really more about why literal values can't seem be passed by reference.知道这一点真是太好了,所以谢谢大家,即便如此,我的问题实际上更多是关于为什么文字值似乎不能通过引用传递。 which has been addressed by the accepted answer.已通过接受的答案解决。

You cannot bind a literal to an lvalue reference to non-const (because modifying the value of a literal is not an operation that makes sense). 您不能将文字绑定到非const的左值引用(因为修改文字的值不是一个有意义的操作)。 You can however bind a literal to a reference to const. 但是,您可以将文字绑定到对const的引用。

So this will compile if you declare fillRect as: 因此,如果您将fillRect声明为:

void fillRect(int const& x, int const& y, int const& width, int const& height)

In this case you are passing int s. 在这种情况下,您传递的是int int s are so cheap to copy that passing by them by reference will probably make the performance of your program worse. int s复制起来非常便宜,通过引用传递它们可能会使程序的性能变差。

The function fillRect is probably so expensive that the cost of passing its arguments is totally irrelevant in any case. 函数fillRect可能是如此昂贵,以至于传递其参数的成本在任何情况下都是完全无关紧要的。 Or maybe it will be inlined, and there will be no cost whatsoever to passing the arguments. 或者也许它会被内联,并且传递参数不会有任何代价。 These sorts of micro-optimisations are usually not optimisations at all, and should always be guided by the results of profiling (if they are done at all). 这些微观优化通常都不是优化,应始终以分析结果为指导(如果完成的话)。

To avoid the inefficiency of copy-by-value when calling a function 在调用函数时避免复制值的低效率

Stop right there. 停在那儿。

Passing by reference does not necessarily mean "fast". 通过引用传递并不一定意味着“快速”。 This goes doubly so for basic types. 而去,基本类型。 Indeed, accessing basic types by reference will be slower than doing so by value. 实际上,通过引用访问基本类型比通过值访问更慢 A reference is not magic. 参考不是魔术。 It's generally implemented as a pointer. 它通常作为指针实现。 So every time you access that value, you are likely doing a pointer dereference. 因此,每次访问该值时,您都可能会执行指针取消引用。

This sounds like some kind of micro-optimization. 这听起来像某种微优化。 Do not optimize without profiling. 不进行分析就不要优化。 Unless you have really good reason to expect the performance of your application to hinge on value vs. reference parameters, just do what makes sense. 除非您有充分的理由期望应用程序的性能取决于值与参考参数,否则只需做有意义的事情。

You should only pass basic types by reference if you intend to modify them. 如果要修改基本类型,则应仅通过引用传递基本类型。

Passing by reference is actually slower for such small values. 对于这样小的值,通过引用传递实际上更慢。 To pass by reference, it is, under-the-hood, passing a pointer (which is an int-sized value anyway). 要通过引用传递,它是在引擎盖下传递一个指针(无论如何都是一个int大小的值)。 Then, there is a hidden extra pointer indirection that is not free. 然后,有一个隐藏的额外指针间接不是免费的。 It is more direct to simply pass the value. 简单地传递该值更直接。

Do this: 做这个:

void fillRect( int x, int y, int width, int height )
{
    // do something
}

The compiler will most likely inline your function anyway, unless its big. 编译器很可能无论如何都会内联你的函数,除非它很大。 So you wouldn't have been able to improve the performance by being "clever" in how you declared the function. 所以你不能通过在声明函数方面“聪明”来提高性能。

First you should take heed of the other's advice to prefer passing by value for simple types. 首先,你应该注意对方的建议,更喜欢通过简单类型的值传递。 C (and by extension C++) were designed with this use case in mind, and that's what they're optimized for. C(以及扩展的C ++)在设计时考虑了这个用例,这就是他们优化的用途。

Second you should always use a const reference unless you intend to modify the variable. 其次,除非您打算修改变量,否则应始终使用const引用。 A literal can be bound to a const reference but not a non-const one. 文字可以绑定到const引用,但不能绑定到非const引用。

You seem to already be familiar with the problems of copy-by- value , so you've eliminated copy-by- value . 您似乎已经熟悉了按复制的问题,因此您已经消除了复制的问题。 And now you're confused that passing raw values fails? 现在你很困惑,传递原始失败了吗?

Now I'm lost. 现在我迷路了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM