&x[x.size()]
would result in (attempting to) take the address of x[x.size()]
. However x[x.size()]
attempts to access an out of bound element; depending on the API of Vector<T>::operator[]
for the particular T
, a number of bad things could happen:
| Vector<T>::operator[] semantics |
| ======================================= |
| return\ contr | | |
| type \ -act | unchecked | checked |
| --------------------------------------- |
| reference | UB (1) | FH |
| value | UB (2) | FH |
| --------------------------------------- |
with
- UB (1): undefined behavior when creating a reference to an out-of-range-element.
- UB (2): undefined behaviour when attempting to read the value of an out-of-range element.
- FH: some fault handling action from the API if it is checked (e.g. throwing an exception, terminating, ...).
For std::vector
, as an example, you would run into UB (1) as its operator[]
is unchecked and returns a reference type.
Whilst you may perform pointer arithmetics to compute a pointer to one-past-last (semantically end()
) of a buffer, you may not dereference a one-past-last pointer.
x.size()
bytes' but ratherx.size()
times the size of each item. And the size of an item follows from the type of a pointer obtained by&x[0]
. Seek the notion of 'pointer arithmetic' in C/C++. – Maledict