Skip to content

Reference Semantics

In reference semantics, objects are accessed via indirection (pointer or reference). The inherent risk of this that references can become invalidated.

Reference Semantics using pointers also bring the question of ownership: Who will clean up?

  • For a raw T* it is not explicit and can be unclear. Follow convention: R.3: A raw pointer (a T*) is non-owning
  • For a std::unique_ptr it is clear, as it actually implements Value Semantics
  • For a std::shared_ptr, it is whoever holds the last reference, which is ambiguous.

Example that demonstrates a risk of reference semantics

Section titled “Example that demonstrates a risk of reference semantics”
std::vector<int> vec { 1, 4, 3, 4, 3, 1};
// max_element: find largest element (4)
auto const pos = std::max_element(begin(vec), end(vec));
// Remove largest element using remove-erase idiom
vec.erase(std::remove(begin(vec, end(vec), *pos), end(vec));
print(vec); //out: 1 3 4 1
// 3's have been removed instead of 4's!

The unintended behavior happens because because pos is a reference in std::remove(It, It, T&).

Source: Klaus Iglberger presentation in youtube (?)

Value Semantics std::span