C++ Reference Collapsing | Rules for T& and T&&

C++ Reference Collapsing | Rules for T& and T&&

이 글의 핵심

The four reference-collapsing rules and how they connect to universal references and perfect forwarding.

What is reference collapsing?

You cannot write int& & directly, but nested references can appear through aliases, templates, and decltype. The compiler collapses them:

T&  &   -> T&
T&  &&  -> T&
T&& &   -> T&
T&& &&  -> T&&

Rule of thumb: if any & is involved, the result is &; only && + && stays &&.

With forwarding references

template<typename T>
void func(T&& arg) {}

int x = 10;
func(x);       // T = int&,   T&& -> int& && -> int&
func(10);      // T = int,    T&& -> int&&

auto&&

int x = 10;
auto&& a = x;           // int& (collapsing)
auto&& b = 10;          // int&&

std::forward sketch

template<typename T>
T&& forward(typename std::remove_reference_t<T>& arg) noexcept {
    return static_cast<T&&>(arg);
}

Pitfalls

  • std::move in a forwarding wrapper forces rvalue—use std::forward<T> when preserving category.
  • decltype((x)) can introduce references—pair with remove_reference_t when needed.

  • Universal reference
  • Perfect forwarding

Keywords

C++, reference collapsing, forwarding reference, templates, C++11