Скотт Мейєрс у «Ефективному і сучасному C++» (2014) писав: без ясного розуміння виведення типів ефективне програмування сучасним C++ неможливе — занадто багато контекстів: шаблони функцій, auto, decltype, з C++14 ще й decltype(auto).
Це твердження лишається актуальним і для C++20 / C++23. Фундаментальні правила для template, auto, decltype і decltype(auto) ніхто не скасовував і не спрощував — на них тримається зворотна сумісність. Нові стандарти розширили місця, де виведення з’являється.
Що додалося з C++14 до C++20 / C++23
CTAD (C++17, покращено в C++20)
Раніше виведення параметрів шаблону класу з конструктора не працювало. Тепер:
std::pair p(10, 3.14); // std::pair<int, double>
std::vector v = {1, 2, 3}; // std::vector<int>
Скорочені шаблони функцій через auto (C++20)
auto у списку параметрів робить функцію шаблоном; правила ті самі, що для звичайних шаблонів функцій:
void print(auto val); // еквівалентно template <typename T> void print(T val)
Концепти та обмежений auto (C++20)
std::integral auto x = compute(); // тип виводиться, але має бути цілочисельним
Structured Binding (auto [a, b] — C++17)
auto [id, name] = get_user();
Нюанс: дедукція застосовується до прихованої змінної; a і b — псевдоніми елементів, а не окремі оголошення з тими самими специфікаторами.
auto у нетипових параметрах шаблонів (NTTP — C++17 / C++20)
template <auto Value>
struct ConstantHolder {};
Deducing this (C++23)
Об’єкт виклику можна передати явним першим параметром; Self виводиться з урахуванням const і категорії значення:
struct Widget {
template <typename Self>
void foo(this Self&& self) {
// Self залежить від того, як викликали метод
}
};
Це зменшує дублювання const / & / && методів, але вимагає розуміння універсальних посилань і виведення типів.
Базові сценарії для шаблонів / auto / decltype — у нотатці про три стовпи виведення. CTAD і гайди — окремо; structured binding і deducing this — у наступних нотатках цієї серії.