#auto& vs auto&&

56 messages · Page 1 of 1 (latest)

celest bobcat
#

When should I use

for(auto&& v : vector)

over

for(auto& v : vector)

for range based loops?

royal heraldBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.

weak wind
#

I can't imagine any case where the former is preferable

#

or even makes sense

celest bobcat
#

why does it even exist

weak wind
#

so && means an R-Value reference

#

are you famliar with what the difference between L and R values

celest bobcat
weak wind
#

Pretty much

#

;compile

#include <cstdio>

void print(int& a) {
    printf("%d is from an L-Value\n", a);
}

void print(int&& a) {
    printf("%d is from an R-Value\n", a);
}

int main() {
    int a = 5;
    int b = 3;
    print(a);
    print(a + b);
}
flint cosmosBOT
#
Program Output
5 is from an L-Value
8 is from an R-Value
celest bobcat
weak wind
#

a is an L value
a+b is an R value

celest bobcat
#

okay okay I see

#

don't you want to use auto&& since it has extra abilities?

#

I'm reading it binds to both l value and r value

#

it will bind to anything (lvalue or rvalue, const or modifiable.)

weak wind
#

thinking...

#

;compile

for (auto&& x : std::vector{1, 2, 3, 4, 5}) {
    printf("%d\n", x);
}
flint cosmosBOT
#
Program Output
1
2
3
4
5
weak wind
#

;compile

for (auto& x : std::vector{1, 2, 3, 4, 5}) {
    printf("%d\n", x);
}
flint cosmosBOT
#
Program Output
1
2
3
4
5
weak wind
#

I guess I struggle to see a context that you ever get an R-value

#

and if you do, I am concerned about getting a use after free issue

#

;compile

#include <cstdio>

void print(int& a) {
    printf("%d is from an L-Value\n", a);
}

void print(int&& a) {
    printf("%d is from an R-Value\n", a);
}

int main() {
    int a = 5;
    int b = 3;
    auto&& c = a + b;
    print(c);
    c = 10;
    print(c);
}
flint cosmosBOT
#
Program Output
8 is from an L-Value
10 is from an L-Value
celest bobcat
#

The only time you'd need to use a universal reference is if you're dealing with a container that has iterators that return rvalue references when dereferenced

#

I'm using an iterator for my loops

weak wind
#

if you are looping over a vector, the iterator is not returning an r-value when dereferenced

celest bobcat
#

I haven't tested it whether it's l or r

weak wind
#

it would be an l-value

celest bobcat
#

I look at an example, they use auto&&

weak wind
#

"they" being?

celest bobcat
#

not sure, some coding site

#

probably stack overflow

#

also

weak wind
#

okay counterpoint, you should never use vector<bool>

#

but ya that makes sense

loud tendon
weak wind
#

okay to be fair, at the time, I thought auto&& was only universal in the context of template function arguments

loud tendon
#

k^^

#

then I don't need to explain that part anymore ^^

weak wind
#

also assigning by r-value reference outside the context of function arguments fucks with my intuition of object lifetimes

#

;compile

#include <cstdio>

struct INNER {
  INNER() {
    printf("INNER con\n"); 
  }

  ~INNER() {
    printf("INNER dcon\n");
  }
};

struct OUTER {
  INNER inner;
  OUTER() {
    printf("OUTER con\n"); 
  }

  ~OUTER() {
    printf("OUTER dcon\n");
  }
};

int main() {
   printf("a\n");
   OUTER&& a = OUTER{};
   printf("b\n");
   INNER&& b = OUTER{}.inner;
   printf("end\n");
}
flint cosmosBOT
#
Program Output
a
INNER con
OUTER con
b
INNER con
OUTER con
end
OUTER dcon
INNER dcon
OUTER dcon
INNER dcon
celest bobcat
#

in layman terms

weak wind
#

forwarding means passing the R/L-valueness of a function argument to another function
proxy means a non reference object that acts like a reference of a type

celest bobcat
#

for forwarding

weak wind
#

;compile

#include <cstdio>
#include <utility>

void print(int& a) {
    printf("%d is from an L-Value\n", a);
}

void print(int&& a) {
    printf("%d is from an R-Value\n", a);
}

template <typename T>
void print_forward(T&& a) {
    print(std::forward<T>(a));
}

template <typename T>
void print_noforward(T&& a) {
    print(a);
}

int main() {
    int a = 5;
    int b = 3;
    printf("FORWARD\n");
    print_forward(a);
    print_forward(a+b);
    printf("NO FORWARD\n");
    print_noforward(a);
    print_noforward(a+b);
}
flint cosmosBOT
#
Program Output
FORWARD
5 is from an L-Value
8 is from an R-Value
NO FORWARD
5 is from an L-Value
8 is from an L-Value
celest bobcat
#

tyvm

#

!solved