In C ++, what I consider to be an anti-pattern using const T& very common as a smart way to just say T when working with parameters. However, a value and a link (whether it is constant or not) are two completely different things, and always blindly using links instead of values can lead to minor errors.
The reason is that when working with links you have to consider two problems that are not in the values: lifetime and aliases .
Just as an example, one of the places where this anti-pattern is applied is the standard library itself, where std::vector<T>::push_back takes const T& instead of a value, and this can lead, for example, to code:
std::vector<T> v; ... if (v.size()) v.push_back(v[0]);
This code is a ticking bomb because std::vector::push_back wants a link to const, but doing push_back may require redistribution, and if that happens, it means that after redistribution, the received link will no longer be valid (life time problem), and you will enter an area of vague behavior.
Problems with aliases are also a source of subtle problems if constant references are used instead of values. For example, I was bitten by code of this type:
struct P2d { double x, y; P2d(double x, double y) : x(x), y(y) {} P2d& operator+=(const P2d& p) { x+=px; y+=py; return *this; } P2d& operator-=(const P2d& p) { x-=px; y-=py; return *this; } }; struct Rect { P2d tl, br; Rect(const P2d& tl, const P2d& br) : tl(tl), bt(br) {} Rect& operator+=(const P2d& p) { tl+=p; br+=p; return *this; } Rect& operator-=(const P2d& p) { tl-=p; br-=p; return *this; } };
At first glance, the code seems pretty safe, P2d is a two-dimensional point, Rect is a rectangle, and adding / subtracting a point means translating the rectangle.
However, if you want to translate the rectangle back to the origin, write myrect -= myrect.tl; the code will not work because the translation operator was defined by accepting a link that (in this case) refers to a member of the same instance.
This means that after updating topleft with tl -= p; topleft will be (0, 0) as it should be, but also p will become (0, 0) at the same time because p is just a reference to the upper left member, and therefore updating the lower right corner will not work because it will translate it as (0, 0) therefore, doing nothing.
Please do not think that the reference to const is similar to the meaning due to the word const . This word exists only to inform you of compilation errors if you are trying to modify the reference object using this link, but does not mean that the reference object is a constant. More precisely, the object referenced by const ref may change (for example, due to aliases) and may even cease to exist while you use it (life time problem).
In const T& word const expresses a property of a link, not a reference object: it is a property that makes it impossible to use it to modify the object. Readonly would probably be a better name, since const has an IMO psychological effect on the idea that the object will be persistent while you use the link.
Of course, you can achieve impressive acceleration by using links instead of copying values, especially for large classes. But when using links, you should always think about problems with aliases and lifetimes, because undercover they simply point to other data. However, for "native" data types (integer, double, pointers), references will actually be slower than values, and when used instead of values, there is nothing to gain.
Also, a link to const will always mean problems for the optimizer, since the compiler is forced to be paranoid, and every time any unknown code is executed, it should assume that all the reference objects can now have a different value ( const means absolutely NOTHING for the optimizer for the link , this word is only to help programmers - personally, I'm not sure that this is such a big help, but this is a different story).