Scott Meyers wrote in Effective Modern C++ (2014) that without a clear model of type deduction, effective modern C++ is impractical — there are too many contexts: function templates, auto, decltype, and since C++14 also decltype(auto).

That claim still holds for C++20 / C++23. The fundamental rules for template, auto, decltype, and decltype(auto) were not cancelled or simplified — language compatibility rests on them. Later standards added more places where deduction appears.

What landed from C++14 to C++20 / C++23

CTAD (C++17, improved in C++20)

Class template parameters can be deduced from constructor arguments:

std::pair p(10, 3.14);   // std::pair<int, double>
std::vector v = {1, 2, 3}; // std::vector<int>

Abbreviated function templates via auto (C++20)

auto in a parameter list makes the function a template; the same deduction rules as ordinary function templates apply:

void print(auto val); // equivalent to template <typename T> void print(T val)

Concepts and constrained auto (C++20)

std::integral auto x = compute(); // type is deduced, but must be integral

Structured binding (auto [a, b] — C++17)

auto [id, name] = get_user();

Nuance: deduction applies to a hidden variable; a and b are aliases for elements, not separate declarations carrying those same specifiers.

auto in non-type template parameters (NTTP — C++17 / C++20)

template <auto Value>
struct ConstantHolder {};

Deducing this (C++23)

The object of the call can be an explicit first parameter; Self is deduced with const and value category in mind:

struct Widget {
    template <typename Self>
    void foo(this Self&& self) {
        // Self depends on how the method was called
    }
};

This cuts down duplicated const / & / && methods, but it requires a solid grasp of forwarding references and type deduction.


The core template / auto / decltype scenarios are in the note on the three pillars of deduction. CTAD and guides are covered separately; structured binding and deducing this continue in the following notes in this series.