2

Say we have a function that accepts a parameter, and this parameter will only be used for reading. Now we don't want to copy the passed in parameter, rather we just want to move it (for efficiency reasons).

Is there any difference between passing it as a const T & and a T &&? and which should be used.

Here's an example


void    printRange(const int & start, const int & stop)
{
    for ( int i = start; i < stop; ++i)
        std::cout << i << std::endl;
}

/*                      VS                              */

void    printRange(int && start, int && stop)
{
    for ( int i = start; i < stop; ++i)
        std::cout << i << std::endl;
}

Is there a difference? What is it? and what is the better choice?


Here taking the integers by value would be the way to go:

"Because when you take them by value, they are local variables. Reference can refer to global mutable variable, so technically, start and end can change inside any function call. Because of that, the compiler cannot elide the loads and must dereference the variable everytime. Take this for example: godbolt disection of code.

As you can see, a bit after the label .L3 (it's the loop) you can see cmp DWORD PTR [rbp+0], ebx. That's a pointer dereference load. In the value version, both int simply sits in registers.

Also, when passing a reference around, you acutally are passing a pointer. That pointer is 8 bytes. So you are passing 16 bytes worth of parameter. Simply ints on the other hand are 4 bytes. Passing a int around by value, even with optimisation off is technically lighter.

Read this, that's also a good explanation by a university professor… And... there is also aliasing. If the ints are by reference, they can both alias each other, so it's also harder for the optimizer I think that's all. Maybe there is other factor I don't know."

-@GuillaumeRacicot

AymenTM
  • 529
  • 2
  • 5
  • 17

1 Answers1

0

Use the first one.

Second can only take "temporaries".

Jarod42
  • 203,559
  • 14
  • 181
  • 302