#auto& vs auto&&
56 messages · Page 1 of 1 (latest)
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.
What does auto&& do that auto& donot
why does it even exist
so && means an R-Value reference
are you famliar with what the difference between L and R values
L means identifiable by memory address and R is the opposite?
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);
}
5 is from an L-Value
8 is from an R-Value
how is it different?
It becomes print(5), and print(8)
a is an L value
a+b is an R value
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.)
thinking...
;compile
for (auto&& x : std::vector{1, 2, 3, 4, 5}) {
printf("%d\n", x);
}
1
2
3
4
5
;compile
for (auto& x : std::vector{1, 2, 3, 4, 5}) {
printf("%d\n", x);
}
1
2
3
4
5
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);
}
8 is from an L-Value
10 is from an L-Value
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
if you are looping over a vector, the iterator is not returning an r-value when dereferenced
I haven't tested it whether it's l or r
it would be an l-value
I look at an example, they use auto&&
"they" being?
the former is pretty much always preferable unless you do indeed want to restrict it to only mutable lvalue references for some reason.
okay to be fair, at the time, I thought auto&& was only universal in the context of template function arguments
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");
}
a
INNER con
OUTER con
b
INNER con
OUTER con
end
OUTER dcon
INNER dcon
OUTER dcon
INNER dcon
okay what does forwarding and proxy objects mean
in layman terms
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
is it possible to give an example
for forwarding
;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);
}
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