1

Hi I have a quick question - over here it says ranged-based for loops of the form

for ( init-statement (optional) range-declaration : range-expression )

are equivalent to the code:

{
    auto && __range = range-expression ;
    for (auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin)
    {
        range-declaration = *__begin;
        loop-statement
    }
}

So if you do

std::vector<datatype> vector1;
for (auto& datatype : vector1)

it's perfectly acceptable. However if you do

std::vector<datatype>&& vector2 = vector1;
or
std::vector<datatype>&& vector2(vector1);

it doesn't compile. As far as I know you cannot initialize an rvalue reference with an lvalue like vector1. What exactly is going on here and what is the difference between the ranged-based for loop's underlying code and the assignment/construct statements? Thanks!

5
  • 8
    auto && is a forwarding reference, it can bind to both lvalues and rvalues. This is useful for perfect forwarding. Commented May 31, 2024 at 22:42
  • 1
    Forwarding references Commented May 31, 2024 at 23:19
  • Basically auto works using/like template argument deduction. That should answer the question. Commented Jun 1, 2024 at 8:07
  • See this answer in the dupe. What is the meaning of a variable with type auto&&?. Also another dupe: What does auto&& do? Commented Jun 1, 2024 at 8:10
  • Well that was simple :) Commented Jun 2, 2024 at 18:35

1 Answer 1

1

As you observed, std::vector<datatype>&& is indeed an rvalue reference, and it cannot be bind to an lvalue like vector1.

However, in this statement:

auto && __range = range-expression;

__range is not an rvalue reference.

It is in fact a Forwarding reference and can therefore bind to either rvalue or lvalue.

The key difference is the usage of auto in the latter case. It makes it equivalent to T && x where T is a template parameter, as in the following example from the documentation above:

template<class T>
int f(T&& x)                      // x is a forwarding reference
{
    return g(std::forward<T>(x)); // and so can be forwarded
}

A side note:
Forwarding reference are related to the issue of perfect forwarding. See more about it here.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.