Skip to main content

CTAD and Deduction Guides

advanced10 min readLesson 142 of 204

C++17 let the compiler infer template arguments from constructors; C++20 extended it to aliases. Deduction guides are how libraries steer that inference.

Class template argument deduction (CTAD)

std::pair p(1, 2.0); โ€” no <int, double> needed; the constructor's parameters drive deduction. Without CTAD you would write std::pair<int, double> p(1, 2.0);.

Where inference goes wrong: iterator pairs

A constructor template <class It> Box(It first, It last) : items(first, last) {} would deduce Box<int*> from Box b(begin(arr), end(arr)); โ€” the iterator type, not the element type. Deduction guides fix the inference without touching the class:

template <class It>
Box(It first, It last) -> Box<std::iter_value_t<It>>;

The guide says: "when you see this constructor signature, deduce from the value type instead." The standard library ships dozens: std::vector v(begin, end) deduces the element type this way.

C++20: alias CTAD

template <class T> using VecOf = std::vector<T>; โ€” then VecOf v{1, 2, 3}; deduces std::vector<int>. Aliases became first-class deduction citizens in C++20.

Review skill: when a container type comes out "wrong" from a constructor call, suspect the missing guide before suspecting your code.

Now practice

CTAD in AngerThe missing-guide bug class every library author meets, and a deduction guide backed by a scanning constructor.2 challenges ยท ยท ~18 min