0

I was wondering why this line is considered valid:

Entity* const & e = this; 

But this line is not:

Entity* & const e = this;

What does the ampersand actually doing here? Why is putting const on the left of it valid but not on the right? By the way, these lines are part of a constructor in a class called Entity.

Reean
  • 27
  • 5
  • I' mhesitant to use this as a dupe target but it has the answer and more for you: https://stackoverflow.com/questions/3694630/c-const-reference-before-vs-after-type-specifier – NathanOliver Jun 16 '20 at 18:12
  • To get a better answer than it's a reference to a pointer, we need to have some more code for context to tell you what the `&` is doing. – user4581301 Jun 16 '20 at 18:12
  • Read https://stackoverflow.com/questions/7420780/what-is-a-constant-reference-not-a-reference-to-a-constant – cigien Jun 16 '20 at 18:13
  • if you put the const on the right of the ampersand, it makes the ampersand constant, meaning you cannot change its value. when it is on the left, the pointer is the one that is constant, so you can attribute a value to `e` – Hjkl Jun 16 '20 at 18:19

3 Answers3

4

What does the ampersand actually doing here?

It is a punctuator that that designates a reference type. It is similar to how the asterisk designates a pointer type.

Why is putting const on the left of it valid but not on the right

Because const qualifier applies to whatever is on the left side of it1. And if const is to the right of the ampersand, then the qualifier would apply to the reference. But that is not allowed by the language. Const cannot be applied to a reference (unlike it can be applied to a pointer). Such qualification would be meaningless. References cannot be modified regardless.

There is no such thing as const reference in C++. Although colloquially, it is common to use "const reference" when people actually mean reference to const.


1 Except when the qualifier is the left most token in which case it applies to the right const T& is same as T const &. All of this applies to volatile as well.

eerorika
  • 232,697
  • 12
  • 197
  • 326
3

Entity* const & e = this; is a "reference to const pointer to Entity".

Entity* & const e = this; would be a "const reference to pointer to Entity", but references can't be const1, thus you get an error.


1 - Once it's created, you can't "rebind" a reference to make it point to a different object. Because of that, some argue that references "are always const", but it's misleading at least. std::is_const returns false for references, so formally they are never const.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
2

The this pointer is declared as follows:

Entity* const this

which means it is a pointer to the current object, where the value of that pointer itself cannot be modified (i.e. the address that this is pointing to cannot be modified).

In the first example, you are declaring a variable called e which is a reference to an entity (const) pointer, i.e. a reference to a (non-changing) (pointer) to an entity, which matches the type of this.

In the second example, you are declaring a reference to an entity pointer, where the value/address of this actual pointer may change. The const keyword here is not specifying the state of the pointer's address, but is rather specifying that the reference itself will not change, i.e. will not reference a new Entity*.

In fact, as pointed out, the added "const" to qualify a reference will not compile (as it is redundant and makes no sense, references cannot be modified), and therefore the follow is incorrect too:

int x = 5;
int& const y = x;

Hope this helped!

Gary Allen
  • 1,218
  • 1
  • 13
  • 28