Links differ from pointers in that there are things that you cannot do for a link and determine its behavior.
You cannot take the link address, but only what is mentioned. You cannot change the link after creating it.
A T& and a T*const (note that const applies to the pointer, not the specified one) relative to. Taking the address of the actual value of const and changing it, this behavior is undefined, since it modifies (any storage that it uses directly) the link.
Now in practice, you can get the help repository:
struct foo { int& x; };
sizeof(foo) almost certainly be equal to sizeof(int*) . But the compiler may neglect the possibility that someone directly accessing the foo bytes may actually change the value mentioned. This allows the compiler to immediately read the "pointer" link and then never read it again. If we had struct foo{ int* x; } struct foo{ int* x; } , then the compiler would have to prove every time he did *fx that the value of the pointer did not change.
If you had struct foo{ int*const x; } struct foo{ int*const x; } , he again begins to maintain the link, as in his immutability (a change of what was declared const - UB).
The trick I don't know about how to use compilers is to compress the binding binding in lambda.
If you have a lambda that captures data by reference, instead of capturing each value with a pointer, it can only capture the pointer to the stack frame. The offsets of each local variable are compile-time constants from the stack frame pointer.
An exception is links taken by the link, which in the defect report for C ++ remain valid even if the reference variable is outside the scope. Thus, they must be captured by a pseudo-pointer.
For a specific example (if there is a toy):
void part( std::vector<int>& v, int left, int right ) { std::function<bool(int)> op = [&](int y){return y<left && y>right;}; std::partition( begin(v), end(v), op ); }
lambda above can only capture the stack frame pointer and know where left and right refer to it, decreasing its size, instead of writing two int references to (basically a pointer).
Here we have references, implied [&] , whose existence is eliminated more easily than if they were, where the pointers were captured by value:
void part( std::vector<int>& v, int left, int right ) { int* pleft=&left; int* pright=&right; std::function<bool(int)> op = [=](int y){return y<*pleft && y>*pright;}; std::partition( begin(v), end(v), op ); }
There are several other differences between links and pointers.
Link can extend the life time of a temporary.
This is heavily used in for(:) loops. Both for(:) loop definitions rely on extending the link life cycle to avoid unnecessary copies, and for(:) loop users can use auto&& to automatically display the easiest way to wrap completed objects.
struct big { int data[1<<10]; }; std::array<big, 100> arr; arr get_arr(); for (auto&& b : get_arr()) { }
here the reference life extension carefully prevents the appearance of extra copies. If we change make_arr to return a arr const& , it continues to work without any copies. If we change get_arr to return a container that returns the big value of the elements (for example, the input range of the iterator), extra copies are not executed again.
It is in a sense syntactic sugar, but it allows in many cases to maintain the same design without the need for micro-optimization, depending on how things come back or are repeated.
Similarly, forwarding links allow you to process data as const, non-const, lvalue or rvalue intelligently. Timestamps are marked as temporary, data that users no longer need is marked as temporary, data to be saved is marked as lvalue reference values.
Links to benefits have links to non-links, so you can create an rvalue link for a temporary one, and you cannot create a pointer to this temporary place without passing it through the link conversion of the link link to lvalue.